From f6ed099f1738334f9373181d3404f78501d4d764 Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Fri, 25 Nov 2022 21:05:14 +0400 Subject: [PATCH] ios: voice messages - improve hold to record button logic, alert if not allowed (#1424) --- apps/ios/Shared/SimpleXApp.swift | 2 +- .../Chat/ComposeMessage/ComposeView.swift | 20 ++++ .../Chat/ComposeMessage/SendMessageView.swift | 97 +++++++++++++++---- .../Views/UserSettings/PreferencesView.swift | 2 +- .../de.xcloc/Localized Contents/de.xliff | 35 +++++++ .../en.xcloc/Localized Contents/en.xliff | 35 +++++++ .../ru.xcloc/Localized Contents/ru.xliff | 35 +++++++ apps/ios/SimpleXChat/ChatTypes.swift | 44 ++++++++- apps/ios/de.lproj/Localizable.strings | 21 ++++ apps/ios/ru.lproj/Localizable.strings | 23 ++++- 10 files changed, 289 insertions(+), 25 deletions(-) diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index 91f04ee456..459cab70de 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -20,7 +20,7 @@ struct SimpleXApp: App { @AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false @State private var userAuthorized: Bool? @State private var doAuthenticate = false - @State private var enteredBackground: Double? = nil + @State private var enteredBackground: TimeInterval? = nil init() { hs_init(0, nil) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 090c11cbdd..c0fe0e2b7f 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -197,12 +197,14 @@ struct ComposeView: View { resetLinkPreview() }, voiceMessageAllowed: chat.chatInfo.voiceMessageAllowed, + showEnableVoiceMessagesAlert: chat.chatInfo.showEnableVoiceMessagesAlert, startVoiceMessageRecording: { Task { await startVoiceMessageRecording() } }, finishVoiceMessageRecording: { finishVoiceMessageRecording() }, + allowVoiceMessagesToContact: { allowVoiceMessagesToContact() }, keyboardVisible: $keyboardVisible ) .padding(.trailing, 12) @@ -502,6 +504,24 @@ struct ComposeView: View { } } + private func allowVoiceMessagesToContact() { + if case let .direct(contact) = chat.chatInfo { + Task { + do { + var prefs = contactUserPreferencesToPreferences(contact.mergedPreferences) + prefs.voice = Preference(allow: .yes) + if let toContact = try await apiSetContactPrefs(contactId: contact.contactId, preferences: prefs) { + await MainActor.run { + chatModel.updateContact(toContact) + } + } + } catch { + logger.error("ComposeView allowVoiceMessagesToContact, apiSetContactPrefs error: \(responseError(error))") + } + } + } + } + // ? maybe we shouldn't have duration in ComposePreview.voicePreview private func updateComposeVMRFinished() { var preview = composeState.preview diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift index d0ea50d490..3f9f2b834f 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift @@ -13,9 +13,11 @@ struct SendMessageView: View { @Binding var composeState: ComposeState var sendMessage: () -> Void var voiceMessageAllowed: Bool = true + var showEnableVoiceMessagesAlert: ChatInfo.ShowEnableVoiceMessagesAlert = .other var startVoiceMessageRecording: (() -> Void)? = nil var finishVoiceMessageRecording: (() -> Void)? = nil - @State private var longPressingVMR = false + var allowVoiceMessagesToContact: (() -> Void)? = nil + @State private var holdingVMR = false @Namespace var namespace @FocusState.Binding var keyboardVisible: Bool @State private var teHeight: CGFloat = 42 @@ -64,13 +66,21 @@ struct SendMessageView: View { .padding([.bottom, .trailing], 3) } else { let vmrs = composeState.voiceMessageRecordingState - if voiceMessageAllowed, - composeState.message.isEmpty, + if composeState.message.isEmpty, !composeState.editing, (composeState.noPreview && vmrs == .noRecording) - || (vmrs == .recording && longPressingVMR) { - recordVoiceMessageButton() - } else if vmrs == .recording && !longPressingVMR { + || (vmrs == .recording && holdingVMR) { + if voiceMessageAllowed { + RecordVoiceMessageButton( + startVoiceMessageRecording: startVoiceMessageRecording, + finishVoiceMessageRecording: finishVoiceMessageRecording, + holdingVMR: $holdingVMR, + disabled: composeState.disabled + ) + } else { + voiceMessageNotAllowedButton() + } + } else if vmrs == .recording && !holdingVMR { finishVoiceMessageRecordingButton() } else { sendMessageButton() @@ -100,29 +110,74 @@ struct SendMessageView: View { .padding([.bottom, .trailing], 4) } - private func recordVoiceMessageButton() -> some View { - Button(action: { - if !longPressingVMR { - startVoiceMessageRecording?() - } else { - finishVoiceMessageRecording?() + private struct RecordVoiceMessageButton: View { + var startVoiceMessageRecording: (() -> Void)? + var finishVoiceMessageRecording: (() -> Void)? + @Binding var holdingVMR: Bool + var disabled: Bool + @State private var pressed: TimeInterval? = nil + + var body: some View { + Button(action: {}) { + Image(systemName: "mic.fill") + .foregroundColor(.accentColor) + } + .disabled(disabled) + .frame(width: 29, height: 29) + .padding([.bottom, .trailing], 4) + ._onButtonGesture { down in + if down { + holdingVMR = true + pressed = ProcessInfo.processInfo.systemUptime + startVoiceMessageRecording?() + } else { + let now = ProcessInfo.processInfo.systemUptime + if let pressed = pressed, + now - pressed >= 1 { + finishVoiceMessageRecording?() + } + holdingVMR = false + pressed = nil + } + } perform: {} + } + } + + private func voiceMessageNotAllowedButton() -> some View { + Button(action: { + switch showEnableVoiceMessagesAlert { + case .userEnable: + AlertManager.shared.showAlert(Alert( + title: Text("Allow voice messages?"), + message: Text("You need to allow your contact to send voice messages to be able to send them."), + primaryButton: .default(Text("Allow")) { + allowVoiceMessagesToContact?() + }, + secondaryButton: .cancel() + )) + case .askContact: + AlertManager.shared.showAlertMsg( + title: "Voice messages prohibited!", + message: "Please ask your contact to enable sending voice messages." + ) + case .groupOwnerCan: + AlertManager.shared.showAlertMsg( + title: "Voice messages prohibited!", + message: "Only group owners can enable voice messages." + ) + case .other: + AlertManager.shared.showAlertMsg( + title: "Voice messages prohibited!", + message: "Please check yours and your contact preferences." + ) } - longPressingVMR = false }) { Image(systemName: "mic") .foregroundColor(.secondary) } - .simultaneousGesture( - LongPressGesture() - .onEnded { _ in - longPressingVMR = true - startVoiceMessageRecording?() - } - ) .disabled(composeState.disabled) .frame(width: 29, height: 29) .padding([.bottom, .trailing], 4) - } private func finishVoiceMessageRecordingButton() -> some View { diff --git a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift index 269839d29b..5812410429 100644 --- a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift +++ b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift @@ -50,7 +50,7 @@ struct PreferencesView: View { Task { do { var p = fromLocalProfile(profile) - p.preferences = toPreferences(preferences) + p.preferences = fullPreferencesToPreferences(preferences) if let newProfile = try await apiUpdateProfile(profile: p) { await MainActor.run { if let profileId = chatModel.currentUser?.profile.profileId { diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff index c9885b7b0b..77e2fbecba 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -293,6 +293,11 @@ Alle Ihre Kontakte bleiben verbunden. No comment provided by engineer. + + Allow + ***Allow + No comment provided by engineer. + Allow irreversible message deletion only if your contact allows it to you. ***Allow irreversible message deletion only if your contact allows it to you. @@ -313,6 +318,11 @@ ***Allow voice messages only if your contact allows them. No comment provided by engineer. + + Allow voice messages? + ***Allow voice messages? + No comment provided by engineer. + Allow your contacts to irreversibly delete sent messages. ***Allow your contacts to irreversibly delete sent messages. @@ -1913,6 +1923,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v ***Only group owners can change group preferences. No comment provided by engineer. + + Only group owners can enable voice messages. + ***Only group owners can enable voice messages. + No comment provided by engineer. + Only you can irreversibly delete messages (your contact can mark them for deletion). ***Only you can irreversibly delete messages (your contact can mark them for deletion). @@ -1993,6 +2008,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Regelmäßig No comment provided by engineer. + + Please ask your contact to enable sending voice messages. + ***Please ask your contact to enable sending voice messages. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Überprüfen Sie bitte, ob Sie den richtigen Link genutzt haben oder bitten Sie Ihren Kontakt nochmal darum, Ihnen einen Link zuzusenden. @@ -2003,6 +2023,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut. No comment provided by engineer. + + Please check yours and your contact preferences. + ***Please check yours and your contact preferences. + No comment provided by engineer. + Please enter correct current passphrase. Bitte geben Sie das korrekte, aktuelle Passwort ein. @@ -2872,6 +2897,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s ***Voice messages are prohibited in this chat. No comment provided by engineer. + + Voice messages prohibited! + ***Voice messages prohibited! + No comment provided by engineer. + Voice message… ***Voice message… @@ -3027,6 +3057,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Sie dürfen die neueste Version Ihrer Chat-Datenbank NUR auf einem Gerät verwenden, andernfalls erhalten Sie möglicherweise keine Nachrichten mehr von einigen Ihrer Kontakte. No comment provided by engineer. + + You need to allow your contact to send voice messages to be able to send them. + ***You need to allow your contact to send voice messages to be able to send them. + No comment provided by engineer. + You rejected group invitation Sie haben die Gruppeneinladung abgelehnt diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff index 29719bad86..770111e672 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -293,6 +293,11 @@ All your contacts will remain connected No comment provided by engineer. + + Allow + Allow + No comment provided by engineer. + Allow irreversible message deletion only if your contact allows it to you. Allow irreversible message deletion only if your contact allows it to you. @@ -313,6 +318,11 @@ Allow voice messages only if your contact allows them. No comment provided by engineer. + + Allow voice messages? + Allow voice messages? + No comment provided by engineer. + Allow your contacts to irreversibly delete sent messages. Allow your contacts to irreversibly delete sent messages. @@ -1913,6 +1923,11 @@ We will be adding server redundancy to prevent lost messages. Only group owners can change group preferences. No comment provided by engineer. + + Only group owners can enable voice messages. + Only group owners can enable voice messages. + No comment provided by engineer. + Only you can irreversibly delete messages (your contact can mark them for deletion). Only you can irreversibly delete messages (your contact can mark them for deletion). @@ -1993,6 +2008,11 @@ We will be adding server redundancy to prevent lost messages. Periodically No comment provided by engineer. + + Please ask your contact to enable sending voice messages. + Please ask your contact to enable sending voice messages. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Please check that you used the correct link or ask your contact to send you another one. @@ -2003,6 +2023,11 @@ We will be adding server redundancy to prevent lost messages. Please check your network connection and try again. No comment provided by engineer. + + Please check yours and your contact preferences. + Please check yours and your contact preferences. + No comment provided by engineer. + Please enter correct current passphrase. Please enter correct current passphrase. @@ -2872,6 +2897,11 @@ To connect, please ask your contact to create another connection link and check Voice messages are prohibited in this chat. No comment provided by engineer. + + Voice messages prohibited! + Voice messages prohibited! + No comment provided by engineer. + Voice message… Voice message… @@ -3027,6 +3057,11 @@ To connect, please ask your contact to create another connection link and check You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts. No comment provided by engineer. + + You need to allow your contact to send voice messages to be able to send them. + You need to allow your contact to send voice messages to be able to send them. + No comment provided by engineer. + You rejected group invitation You rejected group invitation diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff index 3de49d3121..de3074dc9c 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -293,6 +293,11 @@ Все контакты, которые соединились через этот адрес, сохранятся. No comment provided by engineer. + + Allow + Разрешить + No comment provided by engineer. + Allow irreversible message deletion only if your contact allows it to you. Разрешить необратимое удаление сообщений, только если ваш контакт разрешает это вам. @@ -313,6 +318,11 @@ Разрешить голосовые сообщения, только если их разрешает ваш контакт. No comment provided by engineer. + + Allow voice messages? + Разрешить голосовые сообщения? + No comment provided by engineer. + Allow your contacts to irreversibly delete sent messages. Разрешить вашим контактам необратимо удалять отправленные сообщения. @@ -1913,6 +1923,11 @@ We will be adding server redundancy to prevent lost messages. Только владельцы группы могут изменять предпочтения группы. No comment provided by engineer. + + Only group owners can enable voice messages. + Только владельцы группы могут разрешить голосовые сообщения. + No comment provided by engineer. + Only you can irreversibly delete messages (your contact can mark them for deletion). Только вы можете необратимо удалять сообщения (ваш контакт может помечать их на удаление). @@ -1993,6 +2008,11 @@ We will be adding server redundancy to prevent lost messages. Периодически No comment provided by engineer. + + Please ask your contact to enable sending voice messages. + Попросите у вашего контакта разрешить отправку голосовых сообщений. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Пожалуйста, проверьте, что вы использовали правильную ссылку или попросите, чтобы ваш контакт отправил вам другую ссылку. @@ -2003,6 +2023,11 @@ We will be adding server redundancy to prevent lost messages. Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз. No comment provided by engineer. + + Please check yours and your contact preferences. + Проверьте предпочтения вашего контакта. + No comment provided by engineer. + Please enter correct current passphrase. Пожалуйста, введите правильный пароль. @@ -2872,6 +2897,11 @@ To connect, please ask your contact to create another connection link and check Голосовые сообщения запрещены в этом чате. No comment provided by engineer. + + Voice messages prohibited! + Голосовые сообщения запрещены! + No comment provided by engineer. + Voice message… Голосовое сообщение… @@ -3027,6 +3057,11 @@ To connect, please ask your contact to create another connection link and check Вы должны всегда использовать самую новую версию данных чата, ТОЛЬКО на одном устройстве, инача вы можете перестать получать сообщения от каких то контактов. No comment provided by engineer. + + You need to allow your contact to send voice messages to be able to send them. + Чтобы включить отправку голосовых сообщений, разрешите их вашему контакту. + No comment provided by engineer. + You rejected group invitation Вы отклонили приглашение в группу diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index f87edb7b37..2d33adaee3 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -148,10 +148,17 @@ public struct Preferences: Codable { public static let sampleData = Preferences(fullDelete: Preference(allow: .no), voice: Preference(allow: .yes)) } -public func toPreferences(_ fullPreferences: FullPreferences) -> Preferences { +public func fullPreferencesToPreferences(_ fullPreferences: FullPreferences) -> Preferences { Preferences(fullDelete: fullPreferences.fullDelete, voice: fullPreferences.voice) } +public func contactUserPreferencesToPreferences(_ contactUserPreferences: ContactUserPreferences) -> Preferences { + Preferences( + fullDelete: contactUserPreferences.fullDelete.userPreference.preference, + voice: contactUserPreferences.voice.userPreference.preference + ) +} + public struct Preference: Codable, Equatable { public var allow: FeatureAllowed @@ -229,6 +236,13 @@ public struct FeatureEnabled: Decodable { public enum ContactUserPref: Decodable { case contact(preference: Preference) // contact override is set case user(preference: Preference) // global user default is used + + public var preference: Preference { + switch self { + case let .contact(preference): return preference + case let .user(preference): return preference + } + } } public enum Feature: String, Decodable { @@ -626,6 +640,34 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat { } } + public enum ShowEnableVoiceMessagesAlert { + case userEnable + case askContact + case groupOwnerCan + case other + } + + public var showEnableVoiceMessagesAlert: ShowEnableVoiceMessagesAlert { + switch self { + case let .direct(contact): + if contact.mergedPreferences.voice.userPreference.preference.allow == .no { + return .userEnable + } else if contact.mergedPreferences.voice.contactPreference.allow == .no { + return .askContact + } else { + return .other + } + case let .group(groupInfo): + if !groupInfo.fullGroupPreferences.voice.on { + return .groupOwnerCan + } else { + return .other + } + default: + return .other + } + } + public var ntfsEnabled: Bool { switch self { case let .direct(contact): return contact.chatSettings.enableNtfs diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings index 8985030031..b1a60c17d6 100644 --- a/apps/ios/de.lproj/Localizable.strings +++ b/apps/ios/de.lproj/Localizable.strings @@ -197,6 +197,9 @@ /* No comment provided by engineer. */ "All your contacts will remain connected" = "Alle Ihre Kontakte bleiben verbunden."; +/* No comment provided by engineer. */ +"Allow" = "***Allow"; + /* No comment provided by engineer. */ "Allow irreversible message deletion only if your contact allows it to you." = "***Allow irreversible message deletion only if your contact allows it to you."; @@ -209,6 +212,9 @@ /* No comment provided by engineer. */ "Allow voice messages only if your contact allows them." = "***Allow voice messages only if your contact allows them."; +/* No comment provided by engineer. */ +"Allow voice messages?" = "***Allow voice messages?"; + /* No comment provided by engineer. */ "Allow your contacts to irreversibly delete sent messages." = "***Allow your contacts to irreversibly delete sent messages."; @@ -1359,6 +1365,9 @@ /* No comment provided by engineer. */ "Only group owners can change group preferences." = "***Only group owners can change group preferences."; +/* No comment provided by engineer. */ +"Only group owners can enable voice messages." = "***Only group owners can enable voice messages."; + /* No comment provided by engineer. */ "Only you can irreversibly delete messages (your contact can mark them for deletion)." = "***Only you can irreversibly delete messages (your contact can mark them for deletion)."; @@ -1416,12 +1425,18 @@ /* No comment provided by engineer. */ "PING interval" = "PING-Intervall"; +/* No comment provided by engineer. */ +"Please ask your contact to enable sending voice messages." = "***Please ask your contact to enable sending voice messages."; + /* No comment provided by engineer. */ "Please check that you used the correct link or ask your contact to send you another one." = "Überprüfen Sie bitte, ob Sie den richtigen Link genutzt haben oder bitten Sie Ihren Kontakt nochmal darum, Ihnen einen Link zuzusenden."; /* No comment provided by engineer. */ "Please check your network connection and try again." = "Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut."; +/* No comment provided by engineer. */ +"Please check yours and your contact preferences." = "***Please check yours and your contact preferences."; + /* No comment provided by engineer. */ "Please enter correct current passphrase." = "Bitte geben Sie das korrekte, aktuelle Passwort ein."; @@ -2001,6 +2016,9 @@ /* No comment provided by engineer. */ "Voice messages are prohibited in this chat." = "***Voice messages are prohibited in this chat."; +/* No comment provided by engineer. */ +"Voice messages prohibited!" = "***Voice messages prohibited!"; + /* No comment provided by engineer. */ "waiting for answer…" = "Warten auf Antwort…"; @@ -2121,6 +2139,9 @@ /* No comment provided by engineer. */ "You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." = "Sie dürfen die neueste Version Ihrer Chat-Datenbank NUR auf einem Gerät verwenden, andernfalls erhalten Sie möglicherweise keine Nachrichten mehr von einigen Ihrer Kontakte."; +/* No comment provided by engineer. */ +"You need to allow your contact to send voice messages to be able to send them." = "***You need to allow your contact to send voice messages to be able to send them."; + /* No comment provided by engineer. */ "You rejected group invitation" = "Sie haben die Gruppeneinladung abgelehnt"; diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings index 06fd7a8fc9..cbe7c9c2f4 100644 --- a/apps/ios/ru.lproj/Localizable.strings +++ b/apps/ios/ru.lproj/Localizable.strings @@ -197,6 +197,9 @@ /* No comment provided by engineer. */ "All your contacts will remain connected" = "Все контакты, которые соединились через этот адрес, сохранятся."; +/* No comment provided by engineer. */ +"Allow" = "Разрешить"; + /* No comment provided by engineer. */ "Allow irreversible message deletion only if your contact allows it to you." = "Разрешить необратимое удаление сообщений, только если ваш контакт разрешает это вам."; @@ -209,6 +212,9 @@ /* No comment provided by engineer. */ "Allow voice messages only if your contact allows them." = "Разрешить голосовые сообщения, только если их разрешает ваш контакт."; +/* No comment provided by engineer. */ +"Allow voice messages?" = "Разрешить голосовые сообщения?"; + /* No comment provided by engineer. */ "Allow your contacts to irreversibly delete sent messages." = "Разрешить вашим контактам необратимо удалять отправленные сообщения."; @@ -1311,7 +1317,7 @@ "No group!" = "Группа не найдена!"; /* No comment provided by engineer. */ -"No permission to record voice message" = "Нет разрешения на запись голоса"; +"No permission to record voice message" = "Нет разрешения для записи голосового сообщения"; /* No comment provided by engineer. */ "No received or sent files" = "Нет полученных или отправленных файлов"; @@ -1359,6 +1365,9 @@ /* No comment provided by engineer. */ "Only group owners can change group preferences." = "Только владельцы группы могут изменять предпочтения группы."; +/* No comment provided by engineer. */ +"Only group owners can enable voice messages." = "Только владельцы группы могут разрешить голосовые сообщения."; + /* No comment provided by engineer. */ "Only you can irreversibly delete messages (your contact can mark them for deletion)." = "Только вы можете необратимо удалять сообщения (ваш контакт может помечать их на удаление)."; @@ -1416,12 +1425,18 @@ /* No comment provided by engineer. */ "PING interval" = "Интервал PING"; +/* No comment provided by engineer. */ +"Please ask your contact to enable sending voice messages." = "Попросите у вашего контакта разрешить отправку голосовых сообщений."; + /* No comment provided by engineer. */ "Please check that you used the correct link or ask your contact to send you another one." = "Пожалуйста, проверьте, что вы использовали правильную ссылку или попросите, чтобы ваш контакт отправил вам другую ссылку."; /* No comment provided by engineer. */ "Please check your network connection and try again." = "Пожалуйста, проверьте ваше соединение с сетью и попробуйте еще раз."; +/* No comment provided by engineer. */ +"Please check yours and your contact preferences." = "Проверьте предпочтения вашего контакта."; + /* No comment provided by engineer. */ "Please enter correct current passphrase." = "Пожалуйста, введите правильный пароль."; @@ -2001,6 +2016,9 @@ /* No comment provided by engineer. */ "Voice messages are prohibited in this chat." = "Голосовые сообщения запрещены в этом чате."; +/* No comment provided by engineer. */ +"Voice messages prohibited!" = "Голосовые сообщения запрещены!"; + /* No comment provided by engineer. */ "waiting for answer…" = "ожидается ответ…"; @@ -2121,6 +2139,9 @@ /* No comment provided by engineer. */ "You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." = "Вы должны всегда использовать самую новую версию данных чата, ТОЛЬКО на одном устройстве, инача вы можете перестать получать сообщения от каких то контактов."; +/* No comment provided by engineer. */ +"You need to allow your contact to send voice messages to be able to send them." = "Чтобы включить отправку голосовых сообщений, разрешите их вашему контакту."; + /* No comment provided by engineer. */ "You rejected group invitation" = "Вы отклонили приглашение в группу";