Compare commits

..

13 Commits

Author SHA1 Message Date
JRoberts 85609ef217 android: version 4.2-beta.2 (65) 2022-11-01 10:34:17 +04:00
JRoberts 7631d59695 ios: version 4.2 (87) 2022-11-01 10:09:34 +04:00
Evgeny Poberezkin 38f305bb34 run nix build 2022-10-31 22:02:56 +00:00
JRoberts 290ef9de61 core: update simplexmq (queue rotation) (#1276) 2022-10-31 14:29:38 +04:00
mlanp f38d3b4d7f android / iOS: german translations for v4.2 (#1266)
* android / iOS: german translations for v4.2

* corrections

* Localizable.strings

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>
2022-10-29 14:54:49 +04:00
JRoberts 8f638df7a9 mobile: merge contacts (#1271) 2022-10-28 20:05:04 +04:00
JRoberts 8a121b4442 ci: disable test step for ubuntu-20.04 (#1270) 2022-10-28 15:27:34 +04:00
JRoberts 1bb7a954f5 ios: update library 2022-10-28 15:21:12 +04:00
JRoberts ddd8bd9061 ci: github build tests timeout (#1267) 2022-10-28 14:46:20 +04:00
JRoberts 179b9e093f core: merge contacts when connecting via group link (#1265) 2022-10-27 23:38:03 +04:00
JRoberts 352a4f3d2a core: clean up incognito profiles (#1262) 2022-10-27 14:25:48 +04:00
JRoberts e06d4e5c85 ios: translations for auto-accept (#1263) 2022-10-27 10:47:48 +04:00
JRoberts 385ebd2298 core: update deleteGroupMember logic and its usages (no items & expiration) (#1258) 2022-10-26 13:37:17 +04:00
20 changed files with 416 additions and 202 deletions
+2 -1
View File
@@ -108,7 +108,8 @@ jobs:
echo "::set-output name=bin_path::$(cabal list-bin simplex-chat)"
- name: Unix test
if: matrix.os != 'windows-latest'
if: matrix.os != 'windows-latest' && matrix.os != 'ubuntu-20.04'
timeout-minutes: 10
shell: bash
run: cabal test --test-show-details=direct
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId "chat.simplex.app"
minSdk 29
targetSdk 32
versionCode 64
versionName "4.2-beta.0"
versionCode 65
versionName "4.2-beta.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
@@ -950,6 +950,14 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
chatModel.updateChatInfo(cInfo)
}
}
is CR.ContactsMerged -> {
if (chatModel.hasChat(r.mergedContact.id)) {
if (chatModel.chatId.value == r.mergedContact.id) {
chatModel.chatId.value = r.intoContact.id
}
chatModel.removeChat(r.mergedContact.id)
}
}
is CR.ContactsSubscribed -> updateContactsStatus(r.contactRefs, Chat.NetworkStatus.Connected())
is CR.ContactsDisconnected -> updateContactsStatus(r.contactRefs, Chat.NetworkStatus.Disconnected())
is CR.ContactSubError -> processContactSubError(r.contact, r.chatError)
@@ -12,7 +12,7 @@
<!-- Server info - ChatModel.kt -->
<string name="server_connected">Verbunden</string>
<string name="server_error">Fehler</string>
<string name="server_connecting">verbinde</string>
<string name="server_connecting">Verbinde</string>
<string name="connected_to_server_to_receive_messages_from_contact">Sie sind mit dem Server verbunden, der für den Empfang von Nachrichten mit diesem Kontakt genutzt wird.</string>
<string name="trying_to_connect_to_server_to_receive_messages_with_error">Beim Versuch die Verbindung mit dem Server aufzunehmen, der für den Empfang von Nachrichten mit diesem Kontakt genutzt wird, ist ein Fehler aufgetreten (Fehler: <xliff:g id="errorMsg">%1$s</xliff:g>).</string>
<string name="trying_to_connect_to_server_to_receive_messages">Versuche die Verbindung mit dem Server aufzunehmen, der für den Empfang von Nachrichten mit diesem Kontakt genutzt wird.</string>
@@ -32,9 +32,9 @@
<string name="display_name_connecting">verbinde …</string>
<string name="description_you_shared_one_time_link">Sie haben einen Einmal-Link geteilt</string>
<string name="description_you_shared_one_time_link_incognito">Sie haben Inkognito einen Einmal-Link geteilt</string>
<string name="description_via_contact_address_link">über einen Kontaktadressen Link</string>
<string name="description_via_contact_address_link">Über einen Kontaktadressen Link</string>
<string name="description_via_contact_address_link_incognito">Inkognito über einen Kontaktadressen Link</string>
<string name="description_via_one_time_link">über einen Einmal-Link</string>
<string name="description_via_one_time_link">Über einen Einmal-Link</string>
<string name="description_via_one_time_link_incognito">Inkognito über einen Einmal-Link</string>
<!-- SimpleXAPI.kt -->
@@ -63,7 +63,7 @@
<string name="sender_may_have_deleted_the_connection_request">Der Absender hat möglicherweise die Verbindungsanfrage gelöscht.</string>
<string name="error_deleting_contact">Fehler beim Löschen des Kontakts</string>
<string name="error_deleting_group">Fehler beim Löschen der Gruppe</string>
<string name="error_deleting_contact_request">Fehler beim Löschen der Kontakt-Anfrage</string>
<string name="error_deleting_contact_request">Fehler beim Löschen der Kontaktanfrage</string>
<string name="error_deleting_pending_contact_connection">Fehler beim Löschen der anstehenden Kontaktaufnahme</string>
<!-- background service notice - SimpleXAPI.kt -->
@@ -109,9 +109,9 @@
<string name="notification_preview_mode_contact_desc">Nur Kontakt anzeigen</string>
<string name="notification_display_mode_hidden_desc">Kontakt und Nachricht verbergen</string>
<string name="notification_preview_somebody">Kontakt verbergen:</string>
<string name="notification_preview_new_message">neue Nachricht</string>
<string name="notification_new_contact_request">New contact request</string>
<string name="notification_contact_connected">Сonnected</string>
<string name="notification_preview_new_message">Neue Nachricht</string>
<string name="notification_new_contact_request">Neue Kontaktanfrage</string>
<string name="notification_contact_connected">Verbunden</string>
<!-- local authentication notice - SimpleXAPI.kt -->
<string name="la_notice_title_simplex_lock">SimpleX Sperre</string>
@@ -144,16 +144,16 @@
<string name="edit_verb">Bearbeiten</string>
<string name="delete_verb">Löschen</string>
<string name="delete_message__question">Die Nachricht löschen?</string>
<string name="delete_message_cannot_be_undone_warning">Nachricht wird gelöscht - dies kann nicht rückgängig gemacht werden!</string>
<string name="delete_message_cannot_be_undone_warning">Nachricht wird gelöscht - Dies kann nicht rückgängig gemacht werden!</string>
<string name="for_me_only">Nur für mich</string>
<string name="for_everybody">Für alle</string>
<!-- CIMetaView.kt -->
<string name="icon_descr_edited">bearbeitet</string>
<string name="icon_descr_sent_msg_status_sent">gesendet</string>
<string name="icon_descr_sent_msg_status_unauthorized_send">nicht autorisiertes Senden</string>
<string name="icon_descr_edited">Bearbeitet</string>
<string name="icon_descr_sent_msg_status_sent">Gesendet</string>
<string name="icon_descr_sent_msg_status_unauthorized_send">Nicht autorisiertes Senden</string>
<string name="icon_descr_sent_msg_status_send_failed">Senden fehlgeschlagen</string>
<string name="icon_descr_received_msg_status_unread">ungelesen</string>
<string name="icon_descr_received_msg_status_unread">Ungelesen</string>
<!-- ChatListView.kt -->
<string name="personal_welcome">Willkommen <xliff:g>%1$s</xliff:g>!</string>
@@ -162,9 +162,9 @@
<string name="your_chats">Meine Chats</string>
<string name="contact_connection_pending">verbinde …</string>
<string name="group_preview_you_are_invited">Sie sind zu der Gruppe eingeladen</string>
<string name="group_preview_join_as">beitreten als %s</string>
<string name="group_preview_join_as">Beitreten als %s</string>
<string name="group_connection_pending">verbinde …</string>
<string name="tap_to_start_new_chat">Tippen Sie um einen neuen Chat zu starten</string>
<string name="tap_to_start_new_chat">Tippen Sie, um einen neuen Chat zu starten</string>
<string name="chat_with_developers">Chatten Sie mit den Entwicklern</string>
<string name="you_have_no_chats">Sie haben keine Chats</string>
@@ -184,7 +184,7 @@
<!-- Images - chat.simplex.app.views.chat.item.CIImageView.kt -->
<string name="image_descr">Bild</string>
<string name="icon_descr_waiting_for_image">Warten auf ein Bild</string>
<string name="icon_descr_asked_to_receive">Um Empfang des Bildes gebeten</string>
<string name="icon_descr_asked_to_receive">Es wird um den Empfang eines Bildes gebeten</string>
<string name="icon_descr_image_snd_complete">Bild gesendet</string>
<string name="waiting_for_image">Warten auf ein Bild</string>
<string name="image_will_be_received_when_contact_is_online">Das Bild wird empfangen, wenn Ihr Kontakt online ist, bitte warten oder schauen Sie später nochmal nach!</string>
@@ -222,7 +222,7 @@
<string name="cancel_verb">Abbrechen</string>
<string name="confirm_verb">Bestätigen</string>
<string name="ok">OK</string>
<string name="no_details">keine Details</string>
<string name="no_details">Keine Details</string>
<string name="add_contact">Kontakt hinzufügen</string>
<string name="copied">In die Zwischenablage kopiert</string>
@@ -234,7 +234,7 @@
<string name="create_group">Geheime Gruppe erstellen</string>
<string name="to_share_with_your_contact">(zum Teilen mit Ihrem Kontakt)</string>
<string name="connect_via_link_or_qr_from_clipboard_or_in_person">(Scannen oder Einfügen aus der Zwischenablage)</string>
<string name="only_stored_on_members_devices">(wird nur von Gruppenmitgliedern gespeichert)</string>
<string name="only_stored_on_members_devices">(Wird nur von Gruppenmitgliedern gespeichert)</string>
<!-- GetImageView -->
<string name="toast_permission_denied">Berechtigung verweigert!</string>
@@ -247,7 +247,7 @@
<string name="you_can_connect_to_simplex_chat_founder">Sie können sich <font color="#0088ff">mit <xliff:g id="appNameFull">SimpleX Chat</xliff:g> Entwicklern verbinden, um Fragen zu stellen und Updates zu erhalten</font>.</string>
<string name="to_start_a_new_chat_help_header">Um einen neuen Chat zu starten</string>
<string name="chat_help_tap_button">Schaltfläche antippen</string>
<string name="above_then_preposition_continuation">über, dann:</string>
<string name="above_then_preposition_continuation">Danach die gewünschte Aktion auswählen:</string>
<string name="add_new_contact_to_create_one_time_QR_code"><b>Neuen Kontakt hinzufügen</b>: Um Ihren Einmal-QR-Code für Ihren Kontakt zu erstellen.</string>
<string name="scan_QR_code_to_connect_to_contact_who_shows_QR_code"><b>QR-Code scannen</b>: Um sich mit Ihrem Kontakt zu verbinden, der Ihnen seinen QR-Code zeigt.</string>
<string name="to_connect_via_link_title">Über Link verbinden</string>
@@ -271,7 +271,7 @@
<string name="delete_contact_menu_action">Kontakt löschen</string>
<string name="delete_group_menu_action">Gruppe löschen</string>
<string name="mark_read">Als gelesen markieren</string>
<string name="mark_unread">Mark unread</string>
<string name="mark_unread">Als ungelesen markieren</string>
<string name="set_contact_name">Kontaktname festlegen</string>
<!-- Actions - ChatListNavLinkView.kt -->
@@ -297,7 +297,7 @@
<string name="image_descr_profile_image">Profilbild</string>
<!-- Content Descriptions -->
<string name="icon_descr_close_button">Schließen Schaltfläche</string>
<string name="icon_descr_close_button">Schließen der Schaltfläche</string>
<string name="image_descr_link_preview">Vorschaubild verlinken</string>
<string name="icon_descr_cancel_link_preview">Link Vorschau abbrechen</string>
<string name="icon_descr_settings">Einstellungen</string>
@@ -400,10 +400,10 @@
<string name="delete_address">Adresse löschen</string>
<!-- AcceptRequestsView.kt -->
<string name="contact_requests">***Contact requests</string>
<string name="accept_requests">***Accept requests</string>
<string name="accept_automatically">***Automatically</string>
<string name="section_title_welcome_message">***WELCOME MESSAGE</string>
<string name="contact_requests">Kontaktanfragen</string>
<string name="accept_requests">Anfragen annehmen</string>
<string name="accept_automatically">Automatisch</string>
<string name="section_title_welcome_message">Begrüßungsmeldung</string>
<!-- User profile details - UserProfileView.kt -->
<string name="display_name__field">Angezeigter Name:</string>
@@ -454,8 +454,8 @@
<string name="callstate_received_answer">Antwort erhalten…</string>
<string name="callstate_received_confirmation">Bestätigung erhalten…</string>
<string name="callstate_connecting">Verbindung wird hergestellt…</string>
<string name="callstate_connected">verbunden</string>
<string name="callstate_ended">beendet</string>
<string name="callstate_connected">Verbunden</string>
<string name="callstate_ended">Beendet</string>
<!-- SimpleXInfo -->
<string name="next_generation_of_private_messaging">Die nächste Generation von privatem Messaging</string>
@@ -552,7 +552,7 @@
<string name="send_link_previews">Link-Vorschau senden</string>
<!-- Settings sections -->
<string name="settings_section_title_you">DU</string>
<string name="settings_section_title_you">MEINE DATEN</string>
<string name="settings_section_title_settings">EINSTELLUNGEN</string>
<string name="settings_section_title_help">HILFE</string>
<string name="settings_section_title_develop">ENTWICKLUNG</string>
@@ -570,8 +570,8 @@
<!-- DatabaseView.kt -->
<string name="your_chat_database">Meine Chat-Datenbank</string>
<string name="run_chat_section">CHAT STARTEN</string>
<string name="chat_is_running">Chat läuft</string>
<string name="chat_is_stopped">Chat ist beendet</string>
<string name="chat_is_running">Der Chat läuft</string>
<string name="chat_is_stopped">Der Chat ist beendet</string>
<string name="chat_database_section">CHAT-DATENBANK</string>
<string name="database_passphrase">Datenbank-Passwort</string>
<string name="export_database">Datenbank exportieren</string>
@@ -581,7 +581,7 @@
<string name="delete_database">Datenbank löschen</string>
<string name="error_starting_chat">Fehler beim Starten des Chats</string>
<string name="stop_chat_question">Chat beenden?</string>
<string name="stop_chat_to_export_import_or_delete_chat_database">Beenden Sie den Chat, um die Chat-Datenbank zu exportieren, zu importieren oder zu löschen. Sie können keine Nachrichten empfangen oder senden, solange der Chat angehalten ist.</string>
<string name="stop_chat_to_export_import_or_delete_chat_database">Beenden Sie den Chat, um die Chat-Datenbank zu exportieren, zu importieren oder zu löschen. Solange der Chat angehalten ist, können Sie keine Nachrichten empfangen oder senden.</string>
<string name="stop_chat_confirmation">Beenden</string>
<string name="set_password_to_export">Passwort zum Exportieren festlegen</string>
<string name="set_password_to_export_desc">Die Datenbank ist mit einem zufälligen Passwort verschlüsselt. Bitte ändern Sie es vor dem Exportieren.</string>
@@ -603,17 +603,17 @@
<string name="data_section">DATEN</string>
<string name="delete_files_and_media">Dateien \&amp; Medien löschen</string>
<string name="delete_files_and_media_question">Dateien und Medien löschen?</string>
<string name="delete_files_and_media_desc">Diese Aktion kann nicht rückgängig gemacht werden - alle empfangenen und gesendeten Dateien und Medien werden gelöscht. Bilder mit niedriger Auflösung bleiben erhalten.</string>
<string name="delete_files_and_media_desc">Diese Aktion kann nicht rückgängig gemacht werden - Alle empfangenen und gesendeten Dateien und Medien werden gelöscht. Bilder mit niedriger Auflösung bleiben erhalten.</string>
<string name="no_received_app_files">Keine empfangenen oder gesendeten Dateien</string>
<string name="total_files_count_and_size">%d Datei(en) mit einem Gesamtspeicherverbrauch von %s</string>
<string name="chat_item_ttl_none">nie</string>
<string name="chat_item_ttl_day">1 Tag</string>
<string name="chat_item_ttl_week">1 Woche</string>
<string name="chat_item_ttl_month">1 Monat</string>
<string name="chat_item_ttl_day">täglich</string>
<string name="chat_item_ttl_week">wöchentlich</string>
<string name="chat_item_ttl_month">monatlich</string>
<string name="chat_item_ttl_seconds">%s Sekunde(n)</string>
<string name="delete_messages_after">Löschen der Nachrichten nach</string>
<string name="delete_messages_after">Löschen der Nachrichten</string>
<string name="enable_automatic_deletion_question">Automatisches Löschen von Nachrichten aktivieren?</string>
<string name="enable_automatic_deletion_message">Diese Aktion kann nicht rückgängig gemacht werden - Die gesendeten und empfangenen Nachrichten, welche älter als die Ausgewählten sind, werden gelöscht. Dies kann mehrere Minuten dauern.</string>
<string name="enable_automatic_deletion_message">Diese Aktion kann nicht rückgängig gemacht werden - Alle empfangenen und gesendeten Nachrichten, die über den ausgewählten Zeitraum hinaus gehen, werden gelöscht. Dies kann mehrere Minuten dauern.</string>
<string name="delete_messages">Nachrichten löschen</string>
<string name="error_changing_message_deletion">Fehler beim Ändern der Einstellung</string>
@@ -688,10 +688,10 @@
<string name="you_are_invited_to_group_join_to_connect_with_group_members">Sie sind zu einer Gruppe eingeladen worden. Treten Sie bei, um sich mit Gruppenmitgliedern zu verbinden.</string>
<string name="join_group_button">Beitreten</string>
<string name="join_group_incognito_button">Inkognito beitreten</string>
<string name="joining_group">Gruppe beitreten</string>
<string name="joining_group">Der Gruppe beitreten</string>
<string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">Sie sind dieser Gruppe beigetreten. Sie werden mit dem einladenden Gruppenmitglied verbunden.</string>
<string name="leave_group_button">Verlassen</string>
<string name="leave_group_question">Gruppe verlassen?</string>
<string name="leave_group_question">Die Gruppe verlassen?</string>
<string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">Sie werden von dieser Gruppe keine Nachrichten mehr erhalten. Der Chatverlauf wird beibehalten.</string>
<string name="icon_descr_add_members">Mitglieder einladen</string>
<string name="icon_descr_group_inactive">Gruppe inaktiv</string>
@@ -712,21 +712,21 @@
<string name="group_invitation_expired">Die Gruppeneinladung ist abgelaufen</string>
<!-- Group event chat items -->
<string name="rcv_group_event_member_added">***sie haben <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g> eingeladen.</string>
<string name="rcv_group_event_member_connected">verbunden</string>
<string name="rcv_group_event_member_added">hat <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g> eingeladen.</string>
<string name="rcv_group_event_member_connected">beigetreten</string>
<string name="rcv_group_event_member_left">verlassen</string>
<string name="rcv_group_event_changed_member_role">***changed role of %s to %s</string>
<string name="rcv_group_event_changed_your_role">***changed your role to %s</string>
<string name="rcv_group_event_member_deleted">entfernte <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g>.</string>
<string name="rcv_group_event_user_deleted">hat Sie entfernt</string>
<string name="rcv_group_event_group_deleted">gruppe gelöscht</string>
<string name="rcv_group_event_updated_group_profile">aktualisiertes gruppenprofil</string>
<string name="rcv_group_event_invited_via_your_group_link">***invited via your group link</string>
<string name="snd_group_event_changed_member_role">***you changed role of %s to %s</string>
<string name="snd_group_event_changed_role_for_yourself">***you changed role for yourself to %s</string>
<string name="snd_group_event_member_deleted">sie haben <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g> entfernt.</string>
<string name="snd_group_event_user_left">sie haben verlassen</string>
<string name="snd_group_event_group_profile_updated">gruppenprofil aktualisiert</string>
<string name="rcv_group_event_changed_member_role">änderte die Rolle von %s auf %s</string>
<string name="rcv_group_event_changed_your_role">änderte Ihre Rolle auf %s</string>
<string name="rcv_group_event_member_deleted">entfernte <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g> aus der Gruppe.</string>
<string name="rcv_group_event_user_deleted">hat Sie aus der Gruppe entfernt</string>
<string name="rcv_group_event_group_deleted">Gruppe gelöscht</string>
<string name="rcv_group_event_updated_group_profile">Aktualisiertes Gruppenprofil</string>
<string name="rcv_group_event_invited_via_your_group_link">wurde über Ihren Gruppen-Link eingeladen</string>
<string name="snd_group_event_changed_member_role">Sie haben die Rolle von %s auf %s geändert</string>
<string name="snd_group_event_changed_role_for_yourself">Sie haben Ihre eigene Rolle auf %s geändert</string>
<string name="snd_group_event_member_deleted">entfernt <xliff:g id="member profile" example="alice (Alice)">%1$s</xliff:g> aus der Gruppe.</string>
<string name="snd_group_event_user_left">hat die Gruppe verlassen</string>
<string name="snd_group_event_group_profile_updated">Gruppenprofil aktualisiert</string>
<!-- GroupMemberRole -->
<string name="group_member_role_member">Mitglied</string>
@@ -734,16 +734,16 @@
<string name="group_member_role_owner">Eigentümer</string>
<!-- GroupMemberStatus -->
<string name="group_member_status_removed">entfernt</string>
<string name="group_member_status_left">verlassen</string>
<string name="group_member_status_removed">Entfernt</string>
<string name="group_member_status_left">Verlassen</string>
<string name="group_member_status_group_deleted">Gruppe gelöscht</string>
<string name="group_member_status_invited">eingeladen</string>
<string name="group_member_status_invited">Eingeladen</string>
<string name="group_member_status_introduced">Verbindung (erstellt)</string>
<string name="group_member_status_intro_invitation">Verbindung (eingeladen)</string>
<string name="group_member_status_accepted">Verbindung (akzeptiert)</string>
<string name="group_member_status_announced">Verbindung (angekündigt)</string>
<string name="group_member_status_connected">verbunden</string>
<string name="group_member_status_complete">vollständig</string>
<string name="group_member_status_connected">Verbunden</string>
<string name="group_member_status_complete">Vollständig</string>
<string name="group_member_status_creator">Ersteller</string>
<string name="group_member_status_connecting">verbinden</string>
@@ -770,16 +770,16 @@
<string name="delete_group_for_self_cannot_undo_warning">Die Gruppe wird für Sie gelöscht - dies kann nicht rückgängig gemacht werden!</string>
<string name="button_leave_group">Gruppe verlassen</string>
<string name="button_edit_group_profile">Gruppenprofil bearbeiten</string>
<string name="group_link">***Group link</string>
<string name="button_create_group_link">***Create link</string>
<string name="delete_link_question">***Delete link?</string>
<string name="delete_link">***Delete link</string>
<string name="you_can_share_group_link_anybody_will_be_able_to_connect">***You can share a link or a QR code - anybody will be able to join the group.</string>
<string name="if_you_later_delete_link_you_wont_lose_members">***If you later delete it - you won\'t lose members of the group connected via the link.</string>
<string name="if_you_delete_group_link_you_wont_lose_members">***If you delete it - you won\'t lose members of the group connected via this link.</string>
<string name="all_group_members_will_remain_connected">***All group members will remain connected.</string>
<string name="error_creating_link_for_group">***Error creating group link</string>
<string name="error_deleting_link_for_group">***Error deleting group link</string>
<string name="group_link">Gruppen-Link</string>
<string name="button_create_group_link">Link erzeugen</string>
<string name="delete_link_question">Link löschen?</string>
<string name="delete_link">Link löschen</string>
<string name="you_can_share_group_link_anybody_will_be_able_to_connect">Sie können diesen Link oder QR-Code teilen - Damit kann jede Person der Gruppe beitreten.</string>
<string name="if_you_later_delete_link_you_wont_lose_members">Wenn Sie den Link später löschen, werden Sie keine Gruppenmitglieder verlieren, die der Gruppe darüber beigetreten sind.</string>
<string name="if_you_delete_group_link_you_wont_lose_members">Wenn Sie den Link löschen, werden Sie keine Gruppenmitglieder verlieren, die der Gruppe darüber beigetreten sind.</string>
<string name="all_group_members_will_remain_connected">Alle Gruppenmitglieder bleiben verbunden.</string>
<string name="error_creating_link_for_group">Fehler beim Erzeugen des Gruppen-Links</string>
<string name="error_deleting_link_for_group">Fehler beim Löschen des Gruppen-Links</string>
<!-- For Console chat info section -->
<string name="section_title_for_console">FÜR KONSOLE</string>
@@ -817,7 +817,7 @@
<string name="group_display_name_field">Anzeigename der Gruppe:</string>
<string name="group_full_name_field">Vollständiger Gruppenname:</string>
<string name="group_unsupported_incognito_main_profile_sent">Der Inkognito-Modus wird hier nicht unterstützt - Ihr Hauptprofil wird an die Gruppenmitglieder gesendet</string>
<string name="group_main_profile_sent">Ihr Chat-Profil wird an Gruppenmitglieder gesendet</string>
<string name="group_main_profile_sent">Ihr Chat-Profil wird an die Gruppenmitglieder gesendet</string>
<!-- GroupProfileView.kt -->
+7
View File
@@ -911,6 +911,13 @@ func processReceivedMsg(_ res: ChatResponse) async {
if m.hasChat(toContact.id) {
m.updateChatInfo(cInfo)
}
case let .contactsMerged(intoContact, mergedContact):
if m.hasChat(mergedContact.id) {
if m.chatId == mergedContact.id {
m.chatId = intoContact.id
}
m.removeChat(mergedContact.id)
}
case let .contactsSubscribed(_, contactRefs):
updateContactsStatus(contactRefs, status: .connected)
case let .contactsDisconnected(_, contactRefs):
@@ -87,7 +87,7 @@ struct ChatListNavLink: View {
ChatPreviewView(chat: chat)
.frame(height: rowHeights[dynamicTypeSize])
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
joinGroupButton(groupInfo.hostConnCustomUserProfileId)
joinGroupButton()
if groupInfo.canDelete {
deleteGroupChatButton(groupInfo)
}
@@ -137,7 +137,7 @@ struct ChatListNavLink: View {
}
}
private func joinGroupButton(_ hostConnCustomUserProfileId: Int64?) -> some View {
private func joinGroupButton() -> some View {
Button {
joinGroup(chat.chatInfo.apiId)
} label: {
@@ -179,17 +179,17 @@
</trans-unit>
<trans-unit id="1 day" xml:space="preserve">
<source>1 day</source>
<target>1 Tag</target>
<target>täglich</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="1 month" xml:space="preserve">
<source>1 month</source>
<target>1 Monat</target>
<target>monatlich</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="1 week" xml:space="preserve">
<source>1 week</source>
<target>1 Woche</target>
<target>wöchentlich</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="6" xml:space="preserve">
@@ -253,6 +253,11 @@
<target>Inkognito akzeptieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accept requests" xml:space="preserve">
<source>Accept requests</source>
<target>Anfragen annehmen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Advanced network settings" xml:space="preserve">
<source>Advanced network settings</source>
<target>Erweiterte Netzwerkeinstellungen</target>
@@ -260,7 +265,7 @@
</trans-unit>
<trans-unit id="All group members will remain connected." xml:space="preserve">
<source>All group members will remain connected.</source>
<target>***All group members will remain connected.</target>
<target>Alle Gruppenmitglieder bleiben verbunden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." xml:space="preserve">
@@ -318,6 +323,11 @@
<target>Bilder automatisch akzeptieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Automatically" xml:space="preserve">
<source>Automatically</source>
<target>Automatisch</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve">
<source>Call already ended!</source>
<target>Anruf ist bereits beendet!</target>
@@ -568,6 +578,11 @@
<target>Kontaktname</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact requests" xml:space="preserve">
<source>Contact requests</source>
<target>Kontaktanfragen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Copy" xml:space="preserve">
<source>Copy</source>
<target>Kopieren</target>
@@ -585,7 +600,7 @@
</trans-unit>
<trans-unit id="Create link" xml:space="preserve">
<source>Create link</source>
<target>***Create link</target>
<target>Link erzeugen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create one-time invitation link" xml:space="preserve">
@@ -803,12 +818,12 @@
</trans-unit>
<trans-unit id="Delete link" xml:space="preserve">
<source>Delete link</source>
<target>***Delete link</target>
<target>Link löschen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete link?" xml:space="preserve">
<source>Delete link?</source>
<target>***Delete link?</target>
<target>Link löschen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete message?" xml:space="preserve">
@@ -823,7 +838,7 @@
</trans-unit>
<trans-unit id="Delete messages after" xml:space="preserve">
<source>Delete messages after</source>
<target>Löschen der Nachrichten nach</target>
<target>Löschen der Nachrichten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete old database" xml:space="preserve">
@@ -1028,7 +1043,7 @@
</trans-unit>
<trans-unit id="Error creating group link" xml:space="preserve">
<source>Error creating group link</source>
<target>***Error creating group link</target>
<target>Fehler beim Erzeugen des Gruppen-Links</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error deleting chat database" xml:space="preserve">
@@ -1233,7 +1248,7 @@
</trans-unit>
<trans-unit id="Group link" xml:space="preserve">
<source>Group link</source>
<target>***Group link</target>
<target>Gruppen-Link</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group message:" xml:space="preserve">
@@ -2335,7 +2350,7 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v
</trans-unit>
<trans-unit id="This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes." xml:space="preserve">
<source>This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes.</source>
<target>Diese Aktion kann nicht rückgängig gemacht werden - Die gesendeten und empfangenen Nachrichten, welche älter als die Ausgewählten sind, werden gelöscht. Dies kann mehrere Minuten dauern.</target>
<target>Diese Aktion kann nicht rückgängig gemacht werden - Alle empfangenen und gesendeten Nachrichten, die über den ausgewählten Zeitraum hinaus gehen, werden gelöscht. Dies kann mehrere Minuten dauern.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost." xml:space="preserve">
@@ -2449,7 +2464,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
</trans-unit>
<trans-unit id="Unread" xml:space="preserve">
<source>Unread</source>
<target>***Unread</target>
<target>Ungelesen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Update" xml:space="preserve">
@@ -2532,6 +2547,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Willkommen %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Welcome message" xml:space="preserve">
<source>Welcome message</source>
<target>Begrüßungsmeldung</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="When available" xml:space="preserve">
<source>When available</source>
<target>Wenn verfügbar</target>
@@ -2594,7 +2614,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
</trans-unit>
<trans-unit id="You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." xml:space="preserve">
<source>You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it.</source>
<target>***You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it.</target>
<target>Sie können diesen Link oder QR-Code teilen - Damit kann jede Person der Gruppe beitreten. Wenn Sie den Link später löschen, werden Sie keine Gruppenmitglieder verlieren, die der Gruppe darüber beigetreten sind.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it." xml:space="preserve">
@@ -2868,12 +2888,12 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="changed role of %@ to %@" xml:space="preserve">
<source>changed role of %1$@ to %2$@</source>
<target>***changed role of %1$@ to %2$@</target>
<target>änderte die Rolle von %1$@ auf %2$@</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="changed your role to %@" xml:space="preserve">
<source>changed your role to %@</source>
<target>***changed your role to %@</target>
<target>änderte Ihre Rolle auf %@</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="colored" xml:space="preserve">
@@ -3028,7 +3048,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="indirect (%d)" xml:space="preserve">
<source>indirect (%d)</source>
<target>Indirekt (%d)</target>
<target>indirekt (%d)</target>
<note>connection level description</note>
</trans-unit>
<trans-unit id="invitation to group %@" xml:space="preserve">
@@ -3043,7 +3063,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="invited %@" xml:space="preserve">
<source>invited %@</source>
<target>Sie haben %@ eingeladen</target>
<target>hat %@ eingeladen.</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="invited to connect" xml:space="preserve">
@@ -3053,7 +3073,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="invited via your group link" xml:space="preserve">
<source>invited via your group link</source>
<target>***invited via your group link</target>
<target>wurde über Ihren Gruppen-Link eingeladen</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="italic" xml:space="preserve">
@@ -3078,7 +3098,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="member connected" xml:space="preserve">
<source>connected</source>
<target>verbunden</target>
<target>beigetreten</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="message received" xml:space="preserve">
@@ -3143,12 +3163,12 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="removed %@" xml:space="preserve">
<source>removed %@</source>
<target>Entfernt %@</target>
<target>hat %@ aus der Gruppe entfernt</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="removed you" xml:space="preserve">
<source>removed you</source>
<target>hat Sie entfernt</target>
<target>hat Sie aus der Gruppe entfernt</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="sec" xml:space="preserve">
@@ -3233,12 +3253,12 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="you changed role for yourself to %@" xml:space="preserve">
<source>you changed role for yourself to %@</source>
<target>***you changed role for yourself to %@</target>
<target>Sie haben Ihre eigene Rolle auf %@ geändert</target>
<note>snd group event chat item</note>
</trans-unit>
<trans-unit id="you changed role of %@ to %@" xml:space="preserve">
<source>you changed role of %1$@ to %2$@</source>
<target>***you changed role of %1$@ to %2$@</target>
<target>Sie haben die Rolle von %1$@ auf %2$@ geändert</target>
<note>snd group event chat item</note>
</trans-unit>
<trans-unit id="you left" xml:space="preserve">
@@ -3248,7 +3268,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="you removed %@" xml:space="preserve">
<source>you removed %@</source>
<target>Sie haben %@ entfernt</target>
<target>entfernt %@ aus der Gruppe</target>
<note>snd group event chat item</note>
</trans-unit>
<trans-unit id="you shared one-time link" xml:space="preserve">
@@ -253,6 +253,11 @@
<target>Accept incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accept requests" xml:space="preserve">
<source>Accept requests</source>
<target>Accept requests</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Advanced network settings" xml:space="preserve">
<source>Advanced network settings</source>
<target>Advanced network settings</target>
@@ -318,6 +323,11 @@
<target>Auto-accept images</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Automatically" xml:space="preserve">
<source>Automatically</source>
<target>Automatically</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve">
<source>Call already ended!</source>
<target>Call already ended!</target>
@@ -568,6 +578,11 @@
<target>Contact name</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact requests" xml:space="preserve">
<source>Contact requests</source>
<target>Contact requests</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Copy" xml:space="preserve">
<source>Copy</source>
<target>Copy</target>
@@ -2532,6 +2547,11 @@ To connect, please ask your contact to create another connection link and check
<target>Welcome %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Welcome message" xml:space="preserve">
<source>Welcome message</source>
<target>Welcome message</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="When available" xml:space="preserve">
<source>When available</source>
<target>When available</target>
@@ -253,6 +253,11 @@
<target>Принять инкогнито</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accept requests" xml:space="preserve">
<source>Accept requests</source>
<target>Принимать запросы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Advanced network settings" xml:space="preserve">
<source>Advanced network settings</source>
<target>Настройки сети</target>
@@ -318,6 +323,11 @@
<target>Автоприем изображений</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Automatically" xml:space="preserve">
<source>Automatically</source>
<target>Автоматически</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve">
<source>Call already ended!</source>
<target>Звонок уже завершен!</target>
@@ -568,6 +578,11 @@
<target>Имена контактов</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact requests" xml:space="preserve">
<source>Contact requests</source>
<target>Запросы контактов</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Copy" xml:space="preserve">
<source>Copy</source>
<target>Скопировать</target>
@@ -2532,6 +2547,11 @@ To connect, please ask your contact to create another connection link and check
<target>Здравствуйте %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Welcome message" xml:space="preserve">
<source>Welcome message</source>
<target>Приветственное сообщение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="When available" xml:space="preserve">
<source>When available</source>
<target>Когда возможно</target>
+24 -24
View File
@@ -89,11 +89,6 @@
5CC1C99527A6CF7F000D9FF6 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC1C99427A6CF7F000D9FF6 /* ShareSheet.swift */; };
5CC2C0FC2809BF11000C35E3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FA2809BF11000C35E3 /* Localizable.strings */; };
5CC2C0FF2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FD2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings */; };
5CCA7DED2901E32900C8FEBA /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCA7DE82901E32800C8FEBA /* libgmp.a */; };
5CCA7DEE2901E32900C8FEBA /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCA7DE92901E32800C8FEBA /* libffi.a */; };
5CCA7DEF2901E32900C8FEBA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCA7DEA2901E32800C8FEBA /* libgmpxx.a */; };
5CCA7DF02901E32900C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCA7DEB2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a */; };
5CCA7DF12901E32900C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCA7DEC2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a */; };
5CCA7DF32905735700C8FEBA /* AcceptRequestsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCA7DF22905735700C8FEBA /* AcceptRequestsView.swift */; };
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; };
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; };
@@ -125,6 +120,11 @@
5CFE0921282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; };
5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; };
640F50E327CF991C001E05C2 /* SMPServers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640F50E227CF991C001E05C2 /* SMPServers.swift */; };
6432855F290BEE2B00FBE5C8 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855A290BEE2B00FBE5C8 /* libffi.a */; };
64328560290BEE2B00FBE5C8 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855B290BEE2B00FBE5C8 /* libgmp.a */; };
64328561290BEE2B00FBE5C8 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855C290BEE2B00FBE5C8 /* libgmpxx.a */; };
64328562290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */; };
64328563290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */; };
6440CA00288857A10062C672 /* CIGroupEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440C9FF288857A10062C672 /* CIGroupEventView.swift */; };
6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */; };
6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */; };
@@ -290,11 +290,6 @@
5CC1C99427A6CF7F000D9FF6 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = "<group>"; };
5CC2C0FB2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
5CC2C0FE2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
5CCA7DE82901E32800C8FEBA /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
5CCA7DE92901E32800C8FEBA /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
5CCA7DEA2901E32800C8FEBA /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
5CCA7DEB2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a"; sourceTree = "<group>"; };
5CCA7DEC2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a"; sourceTree = "<group>"; };
5CCA7DF22905735700C8FEBA /* AcceptRequestsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcceptRequestsView.swift; sourceTree = "<group>"; };
5CCD403327A5F6DF00368C90 /* AddContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactView.swift; sourceTree = "<group>"; };
5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanToConnectView.swift; sourceTree = "<group>"; };
@@ -324,6 +319,11 @@
5CFA59CF286477B400863A68 /* ChatArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatArchiveView.swift; sourceTree = "<group>"; };
5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; };
640F50E227CF991C001E05C2 /* SMPServers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMPServers.swift; sourceTree = "<group>"; };
6432855A290BEE2B00FBE5C8 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
6432855B290BEE2B00FBE5C8 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
6432855C290BEE2B00FBE5C8 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a"; sourceTree = "<group>"; };
6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a"; sourceTree = "<group>"; };
6440C9FF288857A10062C672 /* CIGroupEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupEventView.swift; sourceTree = "<group>"; };
6440CA02288AECA70062C672 /* AddGroupMembersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersView.swift; sourceTree = "<group>"; };
6442E0B9287F169300CEC0F9 /* AddGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupView.swift; sourceTree = "<group>"; };
@@ -375,12 +375,12 @@
buildActionMask = 2147483647;
files = (
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
5CCA7DF02901E32900C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a in Frameworks */,
5CCA7DEF2901E32900C8FEBA /* libgmpxx.a in Frameworks */,
5CCA7DED2901E32900C8FEBA /* libgmp.a in Frameworks */,
64328561290BEE2B00FBE5C8 /* libgmpxx.a in Frameworks */,
64328562290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a in Frameworks */,
6432855F290BEE2B00FBE5C8 /* libffi.a in Frameworks */,
64328560290BEE2B00FBE5C8 /* libgmp.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
5CCA7DF12901E32900C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a in Frameworks */,
5CCA7DEE2901E32900C8FEBA /* libffi.a in Frameworks */,
64328563290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -435,11 +435,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
5CCA7DE92901E32800C8FEBA /* libffi.a */,
5CCA7DE82901E32800C8FEBA /* libgmp.a */,
5CCA7DEA2901E32800C8FEBA /* libgmpxx.a */,
5CCA7DEB2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX-ghc8.10.7.a */,
5CCA7DEC2901E32800C8FEBA /* libHSsimplex-chat-4.1.1-YMBxN0i6bGIdLfYB8ndX.a */,
6432855A290BEE2B00FBE5C8 /* libffi.a */,
6432855B290BEE2B00FBE5C8 /* libgmp.a */,
6432855C290BEE2B00FBE5C8 /* libgmpxx.a */,
6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */,
6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -1211,7 +1211,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
@@ -1253,7 +1253,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
@@ -1332,7 +1332,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
@@ -1362,7 +1362,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 87;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
+36 -24
View File
@@ -116,13 +116,13 @@
"~strike~" = "\\~durchstreichen~";
/* No comment provided by engineer. */
"1 day" = "1 Tag";
"1 day" = "täglich";
/* No comment provided by engineer. */
"1 month" = "1 Monat";
"1 month" = "monatlich";
/* No comment provided by engineer. */
"1 week" = "1 Woche";
"1 week" = "wöchentlich";
/* No comment provided by engineer. */
"6" = "6";
@@ -161,6 +161,9 @@
/* No comment provided by engineer. */
"Accept incognito" = "Inkognito akzeptieren";
/* No comment provided by engineer. */
"Accept requests" = "Anfragen annehmen";
/* call status */
"accepted call" = "Anruf angenommen";
@@ -171,7 +174,7 @@
"Advanced network settings" = "Erweiterte Netzwerkeinstellungen";
/* No comment provided by engineer. */
"All group members will remain connected." = "***All group members will remain connected.";
"All group members will remain connected." = "Alle Gruppenmitglieder bleiben verbunden.";
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Alle Nachrichten werden gelöscht - dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht.";
@@ -209,6 +212,9 @@
/* No comment provided by engineer. */
"Auto-accept images" = "Bilder automatisch akzeptieren";
/* No comment provided by engineer. */
"Automatically" = "Automatisch";
/* integrity error chat item */
"bad message hash" = "Ungültiger Nachrichten-Hash";
@@ -261,10 +267,10 @@
"Change role" = "Rolle ändern";
/* rcv group event chat item */
"changed role of %@ to %@" = "***changed role of %1$@ to %2$@";
"changed role of %@ to %@" = "änderte die Rolle von %1$@ auf %2$@";
/* rcv group event chat item */
"changed your role to %@" = "***changed your role to %@";
"changed your role to %@" = "änderte Ihre Rolle auf %@";
/* No comment provided by engineer. */
"Chat archive" = "Datenbank Archiv";
@@ -428,6 +434,9 @@
/* No comment provided by engineer. */
"Contact name" = "Kontaktname";
/* No comment provided by engineer. */
"Contact requests" = "Kontaktanfragen";
/* chat item action */
"Copy" = "Kopieren";
@@ -438,7 +447,7 @@
"Create address" = "Adresse erstellen";
/* No comment provided by engineer. */
"Create link" = "***Create link";
"Create link" = "Link erzeugen";
/* No comment provided by engineer. */
"Create one-time invitation link" = "Erstellen Sie einen einmaligen Einladungslink";
@@ -567,10 +576,10 @@
"Delete invitation" = "Einladung löschen";
/* No comment provided by engineer. */
"Delete link" = "***Delete link";
"Delete link" = "Link löschen";
/* No comment provided by engineer. */
"Delete link?" = "***Delete link?";
"Delete link?" = "Link löschen?";
/* No comment provided by engineer. */
"Delete message?" = "Die Nachricht löschen?";
@@ -579,7 +588,7 @@
"Delete messages" = "Nachrichten löschen";
/* No comment provided by engineer. */
"Delete messages after" = "Löschen der Nachrichten nach";
"Delete messages after" = "Löschen der Nachrichten";
/* No comment provided by engineer. */
"Delete old database" = "Alte Datenbank löschen";
@@ -726,7 +735,7 @@
"Error creating group" = "Fehler beim Erzeugen der Gruppe";
/* No comment provided by engineer. */
"Error creating group link" = "***Error creating group link";
"Error creating group link" = "Fehler beim Erzeugen des Gruppen-Links";
/* No comment provided by engineer. */
"Error deleting chat database" = "Fehler beim Löschen der Chat-Datenbank";
@@ -852,7 +861,7 @@
"Group invitation is no longer valid, it was removed by sender." = "Die Gruppeneinladung ist nicht mehr gültig, sie wurde vom Absender entfernt.";
/* No comment provided by engineer. */
"Group link" = "***Group link";
"Group link" = "Gruppen-Link";
/* notification */
"Group message:" = "Grppennachricht:";
@@ -951,7 +960,7 @@
"Incoming video call" = "Eingehender Videoanruf";
/* connection level description */
"indirect (%d)" = "Indirekt (%d)";
"indirect (%d)" = "indirekt (%d)";
/* No comment provided by engineer. */
"Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)" = "Installieren Sie [SimpleX Chat als Terminalanwendung](https://github.com/simplex-chat/simplex-chat)";
@@ -981,13 +990,13 @@
"invited" = "eingeladen";
/* rcv group event chat item */
"invited %@" = "Sie haben %@ eingeladen";
"invited %@" = "hat %@ eingeladen.";
/* chat list item title */
"invited to connect" = "Für eine Verbindung eingeladen";
/* rcv group event chat item */
"invited via your group link" = "***invited via your group link";
"invited via your group link" = "wurde über Ihren Gruppen-Link eingeladen";
/* No comment provided by engineer. */
"iOS Keychain is used to securely store passphrase - it allows receiving push notifications." = "Für die sichere Speicherung des Passworts wird der iOS Schlüsselbund verwendet - dies erlaubt den Empfang von Push-Benachrichtigungen.";
@@ -1074,7 +1083,7 @@
"Member" = "Mitglied";
/* rcv group event chat item */
"member connected" = "verbunden";
"member connected" = "beigetreten";
/* No comment provided by engineer. */
"Member role will be changed to \"%@\". All group members will be notified." = "Die Mitgliederrolle wird auf \"%@\" geändert. Alle Mitglieder der Gruppe werden benachrichtigt.";
@@ -1341,10 +1350,10 @@
"removed" = "entfernt";
/* rcv group event chat item */
"removed %@" = "Entfernt %@";
"removed %@" = "hat %@ aus der Gruppe entfernt";
/* rcv group event chat item */
"removed you" = "hat Sie entfernt";
"removed you" = "hat Sie aus der Gruppe entfernt";
/* chat item action */
"Reply" = "Antwort";
@@ -1608,7 +1617,7 @@
"This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." = "Diese Aktion kann nicht rückgängig gemacht werden - Alle empfangenen und gesendeten Dateien und Medien werden gelöscht. Bilder mit niedriger Auflösung bleiben erhalten.";
/* No comment provided by engineer. */
"This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes." = "Diese Aktion kann nicht rückgängig gemacht werden - Die gesendeten und empfangenen Nachrichten, welche älter als die Ausgewählten sind, werden gelöscht. Dies kann mehrere Minuten dauern.";
"This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes." = "Diese Aktion kann nicht rückgängig gemacht werden - Alle empfangenen und gesendeten Nachrichten, die über den ausgewählten Zeitraum hinaus gehen, werden gelöscht. Dies kann mehrere Minuten dauern.";
/* No comment provided by engineer. */
"This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost." = "Diese Aktion kann nicht rückgängig gemacht werden - Ihr Profil und Ihre Kontakte, Nachrichten und Dateien gehen unwiderruflich verloren.";
@@ -1680,7 +1689,7 @@
"Unmute" = "Stummschaltung aufheben";
/* No comment provided by engineer. */
"Unread" = "***Unread";
"Unread" = "Ungelesen";
/* No comment provided by engineer. */
"Update" = "Aktualisieren";
@@ -1757,6 +1766,9 @@
/* No comment provided by engineer. */
"Welcome %@!" = "Willkommen %@!";
/* No comment provided by engineer. */
"Welcome message" = "Begrüßungsmeldung";
/* No comment provided by engineer. */
"When available" = "Wenn verfügbar";
@@ -1797,7 +1809,7 @@
"You can set lock screen notification preview via settings." = "Über die Geräte-Einstellungen können Sie die Benachrichtigungsvorschau im Sperrbildschirm erlauben.";
/* No comment provided by engineer. */
"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "***You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it.";
"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "Sie können diesen Link oder QR-Code teilen - Damit kann jede Person der Gruppe beitreten. Wenn Sie den Link später löschen, werden Sie keine Gruppenmitglieder verlieren, die der Gruppe darüber beigetreten sind.";
/* No comment provided by engineer. */
"You can share your address as a link or as a QR code - anybody will be able to connect to you. You won't lose your contacts if you later delete it." = "Sie können Ihre Adresse als Link oder als QR-Code teilen Jeder kann sich darüber mit Ihnen verbinden. Sie werden Ihre mit dieser Adresse verbundenen Kontakte nicht verlieren, wenn Sie diese Adresse später löschen.";
@@ -1809,10 +1821,10 @@
"You can use markdown to format messages:" = "Um Nachrichteninhalte zu formatieren, können Sie Markdowns verwenden:";
/* snd group event chat item */
"you changed role for yourself to %@" = "***you changed role for yourself to %@";
"you changed role for yourself to %@" = "Sie haben Ihre eigene Rolle auf %@ geändert";
/* snd group event chat item */
"you changed role of %@ to %@" = "***you changed role of %1$@ to %2$@";
"you changed role of %@ to %@" = "Sie haben die Rolle von %1$@ auf %2$@ geändert";
/* No comment provided by engineer. */
"You control through which server(s) **to receive** the messages, your contacts the servers you use to message them." = "Sie legen fest, über welche Server Sie Ihre Nachrichten **empfangen** und an Ihre Kontakte **senden**.";
@@ -1845,7 +1857,7 @@
"You rejected group invitation" = "Sie haben die Gruppeneinladung abgelehnt";
/* snd group event chat item */
"you removed %@" = "Sie haben %@ entfernt";
"you removed %@" = "entfernt %@ aus der Gruppe";
/* No comment provided by engineer. */
"You sent group invitation" = "Sie haben eine Gruppeneinladung gesendet";
+12
View File
@@ -161,6 +161,9 @@
/* No comment provided by engineer. */
"Accept incognito" = "Принять инкогнито";
/* No comment provided by engineer. */
"Accept requests" = "Принимать запросы";
/* call status */
"accepted call" = " принятый звонок";
@@ -209,6 +212,9 @@
/* No comment provided by engineer. */
"Auto-accept images" = "Автоприем изображений";
/* No comment provided by engineer. */
"Automatically" = "Автоматически";
/* integrity error chat item */
"bad message hash" = "ошибка хэш сообщения";
@@ -428,6 +434,9 @@
/* No comment provided by engineer. */
"Contact name" = "Имена контактов";
/* No comment provided by engineer. */
"Contact requests" = "Запросы контактов";
/* chat item action */
"Copy" = "Скопировать";
@@ -1757,6 +1766,9 @@
/* No comment provided by engineer. */
"Welcome %@!" = "Здравствуйте %@!";
/* No comment provided by engineer. */
"Welcome message" = "Приветственное сообщение";
/* No comment provided by engineer. */
"When available" = "Когда возможно";
+1 -1
View File
@@ -7,7 +7,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 19aef52135b288dc92c4a2ec6d0be4b8283649ab
tag: 8d9816809f6f05fc13de047ee6662312977be5fc
source-repository-package
type: git
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."19aef52135b288dc92c4a2ec6d0be4b8283649ab" = "0xkhm9hplm55ms34ln7la8zm59ailsxziqbaj5y79z9lafysl15j";
"https://github.com/simplex-chat/simplexmq.git"."8d9816809f6f05fc13de047ee6662312977be5fc" = "066r29zpm82xqwfgqmm5yd880zvksaacp03krif4kspn87hd4qsq";
"https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd";
"https://github.com/simplex-chat/sqlcipher-simple.git"."5e154a2aeccc33ead6c243ec07195ab673137221" = "1d1gc5wax4vqg0801ajsmx1sbwvd9y7p7b8mmskvqsmpbwgbh0m0";
"https://github.com/simplex-chat/aeson.git"."3eb66f9a68f103b5f1489382aad89f5712a64db7" = "0kilkx59fl6c3qy3kjczqvm8c3f4n3p0bdk9biyflf51ljnzp4yp";
+10 -2
View File
@@ -493,7 +493,7 @@ processChatCommand = \case
-- functions below are called in separate transactions to prevent crashes on android
-- (possibly, race condition on integrity check?)
withStore' $ \db -> deleteContactConnectionsAndFiles db userId ct
withStore' $ \db -> deleteContact db userId ct
withStore' $ \db -> deleteContact db user ct
unsetActive $ ActiveC localDisplayName
pure $ CRContactDeleted ct
CTContactConnection -> withChatLock "deleteChat contactConnection" . procCmd $ do
@@ -537,6 +537,8 @@ processChatCommand = \case
maxItemTs_ <- withStore' $ \db -> getGroupMaxItemTs db user gInfo
forM_ filesInfo $ \fileInfo -> deleteFile user fileInfo
withStore' $ \db -> deleteGroupCIs db user gInfo
membersToDelete <- withStore' $ \db -> getGroupMembersForExpiration db user gInfo
forM_ membersToDelete $ \m -> withStore' $ \db -> deleteGroupMember db user m
gInfo' <- case maxItemTs_ of
Just ts -> do
withStore' $ \db -> updateGroupTs db user gInfo ts
@@ -905,7 +907,10 @@ processChatCommand = \case
ci <- saveSndChatItem user (CDGroupSnd gInfo) msg (CISndGroupEvent $ SGEMemberDeleted memberId (fromLocalProfile memberProfile)) Nothing Nothing
toView . CRNewChatItem $ AChatItem SCTGroup SMDSnd (GroupChat gInfo) ci
deleteMemberConnection user m
withStore' $ \db -> updateGroupMemberStatus db userId m GSMemRemoved
withStore' $ \db ->
checkGroupMemberHasItems db user m >>= \case
Just _ -> updateGroupMemberStatus db userId m GSMemRemoved
Nothing -> deleteGroupMember db user m
pure $ CRUserDeletedMember gInfo m {memberStatus = GSMemRemoved}
APILeaveGroup groupId -> withUser $ \user@User {userId} -> do
Group gInfo@GroupInfo {membership} members <- withStore $ \db -> getGroup db user groupId
@@ -1536,6 +1541,8 @@ expireChatItems user ttl sync = do
maxItemTs_ <- withStore' $ \db -> getGroupMaxItemTs db user gInfo
forM_ filesInfo $ \fileInfo -> deleteFile user fileInfo
withStore' $ \db -> deleteGroupExpiredCIs db user gInfo expirationDate createdAtCutoff
membersToDelete <- withStore' $ \db -> getGroupMembersForExpiration db user gInfo
forM_ membersToDelete $ \m -> withStore' $ \db -> deleteGroupMember db user m
withStore' $ \db -> do
ciCount_ <- getGroupCICount db user gInfo
case (maxItemTs_, ciCount_) of
@@ -1703,6 +1710,7 @@ processAgentMessage (Just user@User {userId, profile}) corrId agentConnId agentM
gVar <- asks idsDrg
groupConnIds <- createAgentConnectionAsync user CFCreateConnGrpInv True SCMInvitation
withStore $ \db -> createNewContactMemberAsync db gVar user groupId ct GRMember groupConnIds
probeMatchingContacts ct $ contactConnIncognito ct
_ -> pure ()
Just (gInfo@GroupInfo {membership}, m@GroupMember {activeConn}) -> do
when (maybe False ((== ConnReady) . connStatus) activeConn) $ do
@@ -41,7 +41,7 @@ CREATE TABLE display_names (
CREATE TABLE contacts (
contact_id INTEGER PRIMARY KEY,
contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL, -- NULL if it's an incognito profile
contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL,
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL,
is_user INTEGER NOT NULL DEFAULT 0, -- 1 if this contact is a user
@@ -223,7 +223,7 @@ CREATE TABLE contact_requests (
ON UPDATE CASCADE ON DELETE CASCADE,
agent_invitation_id BLOB NOT NULL,
contact_profile_id INTEGER REFERENCES contact_profiles
ON DELETE SET NULL -- NULL if it's an incognito profile
ON DELETE SET NULL
DEFERRABLE INITIALLY DEFERRED,
local_display_name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
+18 -16
View File
@@ -47,10 +47,10 @@ CREATE TABLE display_names(
) WITHOUT ROWID;
CREATE TABLE contacts(
contact_id INTEGER PRIMARY KEY,
contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL, -- NULL if it's an incognito profile
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL,
is_user INTEGER NOT NULL DEFAULT 0, -- 1 if this contact is a user
contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL,
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL,
is_user INTEGER NOT NULL DEFAULT 0, -- 1 if this contact is a user
via_group INTEGER REFERENCES groups(group_id) ON DELETE SET NULL,
created_at TEXT NOT NULL DEFAULT(datetime('now')),
updated_at TEXT CHECK(updated_at NOT NULL),
@@ -278,18 +278,20 @@ CREATE TABLE contact_requests(
ON UPDATE CASCADE ON DELETE CASCADE,
agent_invitation_id BLOB NOT NULL,
contact_profile_id INTEGER REFERENCES contact_profiles
ON DELETE SET NULL -- NULL if it's an incognito profile
DEFERRABLE INITIALLY DEFERRED,
local_display_name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT(datetime('now')),
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, updated_at TEXT CHECK(updated_at NOT NULL), xcontact_id BLOB,
FOREIGN KEY(user_id, local_display_name)
REFERENCES display_names(user_id, local_display_name)
ON UPDATE CASCADE
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
UNIQUE(user_id, local_display_name),
UNIQUE(user_id, contact_profile_id)
ON DELETE SET NULL
DEFERRABLE INITIALLY DEFERRED,
local_display_name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT(datetime('now')),
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
updated_at TEXT CHECK(updated_at NOT NULL),
xcontact_id BLOB,
FOREIGN KEY(user_id, local_display_name)
REFERENCES display_names(user_id, local_display_name)
ON UPDATE CASCADE
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
UNIQUE(user_id, local_display_name),
UNIQUE(user_id, contact_profile_id)
);
CREATE TABLE messages(
message_id INTEGER PRIMARY KEY,
+76 -14
View File
@@ -83,6 +83,7 @@ module Simplex.Chat.Store
getGroupInfoByName,
getGroupMember,
getGroupMembers,
getGroupMembersForExpiration,
deleteGroupConnectionsAndFiles,
deleteGroupItemsAndMembers,
deleteGroup,
@@ -98,6 +99,7 @@ module Simplex.Chat.Store
updateGroupMemberStatus,
updateGroupMemberStatusById,
createNewGroupMember,
checkGroupMemberHasItems,
deleteGroupMember,
deleteGroupMemberConnection,
updateGroupMemberRole,
@@ -558,8 +560,8 @@ deleteContactConnectionsAndFiles db userId Contact {contactId} = do
(userId, contactId)
DB.execute db "DELETE FROM files WHERE user_id = ? AND contact_id = ?" (userId, contactId)
deleteContact :: DB.Connection -> UserId -> Contact -> IO ()
deleteContact db userId Contact {contactId, localDisplayName} = do
deleteContact :: DB.Connection -> User -> Contact -> IO ()
deleteContact db user@User {userId} Contact {contactId, localDisplayName, activeConn = Connection {customUserProfileId}} = do
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND contact_id = ?" (userId, contactId)
ctMember :: (Maybe ContactId) <- maybeFirstRow fromOnly $ DB.query db "SELECT contact_id FROM group_members WHERE user_id = ? AND contact_id = ? LIMIT 1" (userId, contactId)
if isNothing ctMember
@@ -570,6 +572,25 @@ deleteContact db userId Contact {contactId, localDisplayName} = do
currentTs <- getCurrentTime
DB.execute db "UPDATE group_members SET contact_id = NULL, updated_at = ? WHERE user_id = ? AND contact_id = ?" (currentTs, userId, contactId)
DB.execute db "DELETE FROM contacts WHERE user_id = ? AND contact_id = ?" (userId, contactId)
forM_ customUserProfileId $ \profileId -> deleteUnusedIncognitoProfileById_ db user profileId
deleteUnusedIncognitoProfileById_ :: DB.Connection -> User -> ProfileId -> IO ()
deleteUnusedIncognitoProfileById_ db User {userId} profile_id =
DB.executeNamed
db
[sql|
DELETE FROM contact_profiles
WHERE user_id = :user_id AND contact_profile_id = :profile_id AND incognito = 1
AND 1 NOT IN (
SELECT 1 FROM connections
WHERE user_id = :user_id AND custom_user_profile_id = :profile_id LIMIT 1
)
AND 1 NOT IN (
SELECT 1 FROM group_members
WHERE user_id = :user_id AND member_profile_id = :profile_id LIMIT 1
)
|]
[":user_id" := userId, ":profile_id" := profile_id]
deleteContactProfile_ :: DB.Connection -> UserId -> ContactId -> IO ()
deleteContactProfile_ db userId contactId =
@@ -1324,6 +1345,10 @@ mergeContactRecords db userId Contact {contactId = toContactId} Contact {contact
db
"UPDATE group_members SET invited_by = ?, updated_at = ? WHERE invited_by = ? AND user_id = ?"
(toContactId, currentTs, fromContactId, userId)
DB.execute
db
"UPDATE chat_items SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?"
(toContactId, currentTs, fromContactId, userId)
DB.executeNamed
db
[sql|
@@ -1676,9 +1701,7 @@ deleteGroupItemsAndMembers :: DB.Connection -> User -> GroupInfo -> [GroupMember
deleteGroupItemsAndMembers db user@User {userId} GroupInfo {groupId} members = do
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ?" (userId, groupId)
DB.execute db "DELETE FROM group_members WHERE user_id = ? AND group_id = ?" (userId, groupId)
forM_ members $ \m@GroupMember {groupMemberId, memberContactId, memberContactProfileId} -> unless (isJust memberContactId) $ do
sameProfileMember :: (Maybe GroupMemberId) <- maybeFirstRow fromOnly $ DB.query db "SELECT group_member_id FROM group_members WHERE user_id = ? AND contact_profile_id = ? AND group_member_id != ? LIMIT 1" (userId, memberContactProfileId, groupMemberId)
unless (isJust sameProfileMember) $ deleteMemberProfileAndName_ db user m
forM_ members $ \m -> cleanupMemberContactAndProfile_ db user m
deleteGroup :: DB.Connection -> User -> GroupInfo -> IO ()
deleteGroup db User {userId} GroupInfo {groupId, localDisplayName} = do
@@ -1779,6 +1802,32 @@ getGroupMembers db user@User {userId, userContactId} GroupInfo {groupId} = do
|]
(groupId, userId, userContactId)
getGroupMembersForExpiration :: DB.Connection -> User -> GroupInfo -> IO [GroupMember]
getGroupMembersForExpiration db user@User {userId, userContactId} GroupInfo {groupId} = do
map (toContactMember user)
<$> DB.query
db
[sql|
SELECT
m.group_member_id, m.group_id, m.member_id, m.member_role, m.member_category, m.member_status,
m.invited_by, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
FROM group_members m
JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
LEFT JOIN connections c ON c.connection_id = (
SELECT max(cc.connection_id)
FROM connections cc
where cc.group_member_id = m.group_member_id
)
WHERE m.group_id = ? AND m.user_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?)
AND m.member_status IN (?, ?, ?)
AND m.group_member_id NOT IN (
SELECT DISTINCT group_member_id FROM chat_items
)
|]
(groupId, userId, userContactId, GSMemRemoved, GSMemLeft, GSMemGroupDeleted)
toContactMember :: User -> (GroupMemberRow :. MaybeConnectionRow) -> GroupMember
toContactMember User {userContactId} (memberRow :. connRow) =
(toGroupMember userContactId memberRow) {activeConn = toMaybeConnection connRow}
@@ -1986,19 +2035,32 @@ createNewMember_
groupMemberId <- insertedRowId db
pure GroupMember {groupMemberId, groupId, memberId, memberRole, memberCategory, memberStatus, invitedBy, localDisplayName, memberProfile = toLocalProfile memberContactProfileId memberProfile "", memberContactId, memberContactProfileId, activeConn}
checkGroupMemberHasItems :: DB.Connection -> User -> GroupMember -> IO (Maybe ChatItemId)
checkGroupMemberHasItems db User {userId} GroupMember {groupMemberId, groupId} =
maybeFirstRow fromOnly $ DB.query db "SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? AND group_member_id = ? LIMIT 1" (userId, groupId, groupMemberId)
deleteGroupMember :: DB.Connection -> User -> GroupMember -> IO ()
deleteGroupMember db user@User {userId} m@GroupMember {groupMemberId, groupId, memberContactId, memberContactProfileId} = do
deleteGroupMember db user@User {userId} m@GroupMember {groupMemberId, groupId} = do
deleteGroupMemberConnection db user m
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND group_member_id = ?" (userId, groupId, groupMemberId)
DB.execute db "DELETE FROM group_members WHERE user_id = ? AND group_member_id = ?" (userId, groupMemberId)
unless (isJust memberContactId) $ do
sameProfileMember :: (Maybe GroupMemberId) <- maybeFirstRow fromOnly $ DB.query db "SELECT group_member_id FROM group_members WHERE user_id = ? AND contact_profile_id = ? AND group_member_id != ? LIMIT 1" (userId, memberContactProfileId, groupMemberId)
unless (isJust sameProfileMember) $ deleteMemberProfileAndName_ db user m
cleanupMemberContactAndProfile_ db user m
deleteMemberProfileAndName_ :: DB.Connection -> User -> GroupMember -> IO ()
deleteMemberProfileAndName_ db User {userId} GroupMember {memberContactProfileId, localDisplayName} = do
DB.execute db "DELETE FROM contact_profiles WHERE user_id = ? AND contact_profile_id = ?" (userId, memberContactProfileId)
DB.execute db "DELETE FROM display_names WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName)
-- it's important this function is used in transaction after the actual group_members record is deleted, see checkIncognitoProfileInUse_
cleanupMemberContactAndProfile_ :: DB.Connection -> User -> GroupMember -> IO ()
cleanupMemberContactAndProfile_ db user@User {userId} m@GroupMember {groupMemberId, localDisplayName, memberContactId, memberContactProfileId, memberProfile = LocalProfile {profileId}} =
case memberContactId of
Just contactId ->
runExceptT (getContact db userId contactId) >>= \case
Right ct@Contact {activeConn = Connection {connLevel, viaGroupLink}, contactUsed} ->
unless ((connLevel == 0 && not viaGroupLink) || contactUsed) $ deleteContact db user ct
_ -> pure ()
Nothing -> do
sameProfileMember :: (Maybe GroupMemberId) <- maybeFirstRow fromOnly $ DB.query db "SELECT group_member_id FROM group_members WHERE user_id = ? AND contact_profile_id = ? AND group_member_id != ? LIMIT 1" (userId, memberContactProfileId, groupMemberId)
unless (isJust sameProfileMember) $ do
DB.execute db "DELETE FROM contact_profiles WHERE user_id = ? AND contact_profile_id = ?" (userId, memberContactProfileId)
DB.execute db "DELETE FROM display_names WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName)
when (memberIncognito m) $ deleteUnusedIncognitoProfileById_ db user profileId
deleteGroupMemberConnection :: DB.Connection -> User -> GroupMember -> IO ()
deleteGroupMemberConnection db User {userId} GroupMember {groupMemberId} =
@@ -3122,7 +3184,7 @@ getDirectChatPreviews_ db User {userId} = do
) ChatStats ON ChatStats.contact_id = ct.contact_id
LEFT JOIN chat_items ri ON i.quoted_shared_msg_id = ri.shared_msg_id
WHERE ct.user_id = ?
AND ((c.conn_level = 0 AND c.via_group_link = 0) OR i.chat_item_id IS NOT NULL OR ct.contact_used = 1)
AND ((c.conn_level = 0 AND c.via_group_link = 0) OR ct.contact_used = 1)
AND c.connection_id = (
SELECT cc_connection_id FROM (
SELECT
+1 -1
View File
@@ -49,7 +49,7 @@ extra-deps:
# - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561
# - ../simplexmq
- github: simplex-chat/simplexmq
commit: 19aef52135b288dc92c4a2ec6d0be4b8283649ab
commit: 8d9816809f6f05fc13de047ee6662312977be5fc
# - ../direct-sqlcipher
- github: simplex-chat/direct-sqlcipher
commit: 34309410eb2069b029b8fc1872deb1e0db123294
+62 -20
View File
@@ -138,6 +138,7 @@ chatTests = do
it "set chat item TTL" testSetChatItemTTL
describe "group links" $ do
it "create group link, join via group link" testGroupLink
it "sending message to contact created via group link marks it used" testGroupLinkContactUsed
it "create group link, join via group link - incognito membership" testGroupLinkIncognitoMembership
it "deleting invited member does not leave broken chat item" testGroupLinkDeleteInvitedMemberNoBrokenItem
@@ -768,7 +769,13 @@ testGroupDelete =
cath <## "#team: you deleted the group"
alice <##> bob
alice <##> cath
bob <##> cath
-- unused group contacts are deleted
bob ##> "@cath hi"
bob <## "no contact cath"
(cath </)
cath ##> "@bob hi"
cath <## "no contact bob"
(bob </)
testGroupSameName :: IO ()
testGroupSameName =
@@ -3349,24 +3356,23 @@ testGroupLink =
cath ##> ("/c " <> gLink)
cath <## "connection request sent!"
alice <## "cath_1 (Catherine): accepting request to join group #team..."
-- if contact existed it is merged
concurrentlyN_
[ do
alice <## "cath_1 (Catherine): contact is connected"
alice <## "cath_1 invited to group #team via your group link",
alice <## "cath_1 invited to group #team via your group link"
alice <## "contact cath_1 is merged into cath"
alice <## "use @cath <message> to send messages",
do
cath <## "alice_1 (Alice): contact is connected"
cath <## "#team: alice_1 invites you to join the group as member"
cath <## "contact alice_1 is merged into alice"
cath <## "use @alice <message> to send messages"
cath <## "#team: alice invites you to join the group as member"
cath <## "use /j team to accept"
]
-- sending message to contact marks it as used
alice @@@ [("@cath", "hey"), ("@bob", "hey"), ("#team", "invited via your group link")]
alice #> "@cath_1 hello"
cath <# "alice_1> hello"
alice #$> ("/clear cath_1", id, "cath_1: all messages are removed locally ONLY")
alice @@@ [("@cath_1", ""), ("@cath", "hey"), ("@bob", "hey"), ("#team", "invited via your group link")]
cath ##> "/j team"
concurrentlyN_
[ alice <## "#team: cath_1 joined the group",
[ alice <## "#team: cath joined the group",
do
cath <## "#team: you joined the group"
cath <## "#team: member bob (Bob) is connected",
@@ -3377,14 +3383,14 @@ testGroupLink =
alice #> "#team hello"
concurrently_
(bob <# "#team alice> hello")
(cath <# "#team alice_1> hello")
(cath <# "#team alice> hello")
bob #> "#team hi there"
concurrently_
(alice <# "#team bob> hi there")
(cath <# "#team bob> hi there")
cath #> "#team hey team"
concurrently_
(alice <# "#team cath_1> hey team")
(alice <# "#team cath> hey team")
(bob <# "#team cath> hey team")
-- leaving team removes link
@@ -3394,11 +3400,45 @@ testGroupLink =
alice <## "#team: you left the group"
alice <## "use /d #team to delete the group",
bob <## "#team: alice left the group",
cath <## "#team: alice_1 left the group"
cath <## "#team: alice left the group"
]
alice ##> "/show link #team"
alice <## "no group link, to create: /create link #team"
testGroupLinkContactUsed :: IO ()
testGroupLinkContactUsed =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/g team"
alice <## "group #team is created"
alice <## "use /a team <name> to add members"
alice ##> "/show link #team"
alice <## "no group link, to create: /create link #team"
alice ##> "/create link #team"
gLink <- getGroupLink alice "team" True
alice ##> "/show link #team"
_ <- getGroupLink alice "team" False
alice ##> "/create link #team"
alice <## "you already have link for this group, to show: /show link #team"
bob ##> ("/c " <> gLink)
bob <## "connection request sent!"
alice <## "bob (Bob): accepting request to join group #team..."
concurrentlyN_
[ do
alice <## "bob (Bob): contact is connected"
alice <## "bob invited to group #team via your group link",
do
bob <## "alice (Alice): contact is connected"
bob <## "#team: alice invites you to join the group as member"
bob <## "use /j team to accept"
]
-- sending message to contact marks it as used
alice @@@ [("#team", "invited via your group link")]
alice #> "@bob hello"
bob <# "alice> hello"
alice #$> ("/clear bob", id, "bob: all messages are removed locally ONLY")
alice @@@ [("@bob", ""), ("#team", "invited via your group link")]
testGroupLinkIncognitoMembership :: IO ()
testGroupLinkIncognitoMembership =
testChat4 aliceProfile bobProfile cathProfile danProfile $
@@ -3557,8 +3597,10 @@ testGroupLinkDeleteInvitedMemberNoBrokenItem =
alice <## "#team: you removed bob from the group"
alice #$> ("/_get chat #1 count=100", chat, [])
alice @@@ [("#team", "")]
alice <##> bob
alice @@@ [("@bob", "hey"), ("#team", "")]
-- removing member deletes unused group contact
alice ##> "@bob hi"
alice <## "no contact bob"
(bob </)
bob ##> "/j team"
bob <## "error: connection authorization failed - this could happen if connection was deleted, secured with different credentials, or due to a bug - please re-create the connection"
-- repeat request is prohibited because of the re-used XContactId, until contact is deleted
@@ -3568,11 +3610,11 @@ testGroupLinkDeleteInvitedMemberNoBrokenItem =
bob <## "alice: contact is deleted"
bob ##> ("/c " <> gLink)
bob <## "connection request sent!"
alice <## "bob_1 (Bob): accepting request to join group #team..."
alice <## "bob (Bob): accepting request to join group #team..."
concurrentlyN_
[ do
alice <## "bob_1 (Bob): contact is connected"
alice <## "bob_1 invited to group #team via your group link",
alice <## "bob (Bob): contact is connected"
alice <## "bob invited to group #team via your group link",
do
bob <## "alice_1 (Alice): contact is connected"
bob <## "#team_1 (team): alice_1 invites you to join the group as member"
@@ -3580,12 +3622,12 @@ testGroupLinkDeleteInvitedMemberNoBrokenItem =
]
bob ##> "/j team_1"
concurrently_
(alice <## "#team: bob_1 joined the group")
(alice <## "#team: bob joined the group")
(bob <## "#team_1: you joined the group")
alice #> "#team hello"
bob <# "#team_1 alice_1> hello"
bob #> "#team_1 hi there"
alice <# "#team bob_1> hi there"
alice <# "#team bob> hi there"
withTestChatContactConnected :: String -> (TestCC -> IO a) -> IO a
withTestChatContactConnected dbPrefix action =