From 87d306383c86c458473c9ab9b463cb2bacc72e5f Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Fri, 25 Nov 2022 14:31:37 +0000 Subject: [PATCH] ios: protect screen (#1420) * ios: protect screen * AppSheet * translations * correction Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com> Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com> --- apps/ios/Shared/ContentView.swift | 3 +- apps/ios/Shared/Views/Chat/ChatView.swift | 8 +-- .../Chat/ComposeMessage/ComposeView.swift | 2 +- .../Views/Chat/Group/GroupChatInfoView.swift | 4 +- .../Views/Chat/Group/GroupProfileView.swift | 2 +- .../ChatList/ContactConnectionView.swift | 2 +- apps/ios/Shared/Views/Helpers/AppSheet.swift | 66 +++++++++++++++++++ .../Shared/Views/NewChat/AddGroupView.swift | 2 +- .../Shared/Views/Onboarding/SimpleXInfo.swift | 2 +- .../Views/UserSettings/PrivacySettings.swift | 4 ++ .../Views/UserSettings/SMPServersView.swift | 2 +- .../Views/UserSettings/SettingsButton.swift | 2 +- .../Views/UserSettings/SettingsView.swift | 2 + .../Views/UserSettings/UserProfile.swift | 2 +- .../de.xcloc/Localized Contents/de.xliff | 36 +++++++--- .../en.xcloc/Localized Contents/en.xliff | 36 +++++++--- .../ru.xcloc/Localized Contents/ru.xliff | 36 +++++++--- apps/ios/SimpleX.xcodeproj/project.pbxproj | 4 ++ apps/ios/de.lproj/Localizable.strings | 14 +++- apps/ios/ru.lproj/Localizable.strings | 14 +++- .../ru.lproj/SimpleX--iOS--InfoPlist.strings | 2 +- 21 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 apps/ios/Shared/Views/Helpers/AppSheet.swift diff --git a/apps/ios/Shared/ContentView.swift b/apps/ios/Shared/ContentView.swift index 11e6122b72..1a521edb46 100644 --- a/apps/ios/Shared/ContentView.swift +++ b/apps/ios/Shared/ContentView.swift @@ -17,6 +17,7 @@ struct ContentView: View { @AppStorage(DEFAULT_SHOW_LA_NOTICE) private var prefShowLANotice = false @AppStorage(DEFAULT_LA_NOTICE_SHOWN) private var prefLANoticeShown = false @AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false + @AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = true var body: some View { ZStack { @@ -29,7 +30,7 @@ struct ContentView: View { } else if let step = chatModel.onboardingStage { if case .onboardingComplete = step, chatModel.currentUser != nil { - mainView() + mainView().privacySensitive(protectScreen) } else { OnboardingView(onboarding: step) } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index c8b363a813..62366d0c14 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -103,7 +103,7 @@ struct ChatView: View { } label: { ChatInfoToolbar(chat: chat) } - .sheet(isPresented: $showChatInfoSheet, onDismiss: { + .appSheet(isPresented: $showChatInfoSheet, onDismiss: { connectionStats = nil customUserProfile = nil }) { @@ -121,7 +121,7 @@ struct ChatView: View { } label: { ChatInfoToolbar(chat: chat) } - .sheet(isPresented: $showChatInfoSheet) { + .appSheet(isPresented: $showChatInfoSheet) { GroupChatInfoView(chat: chat, groupInfo: groupInfo) } } @@ -152,7 +152,7 @@ struct ChatView: View { .onTapGesture { AlertManager.shared.showAlert(cantInviteIncognitoAlert()) } } else { addMembersButton() - .sheet(isPresented: $showAddMembersSheet) { + .appSheet(isPresented: $showAddMembersSheet) { AddGroupMembersView(chat: chat, groupInfo: groupInfo) } } @@ -392,7 +392,7 @@ struct ChatView: View { await MainActor.run { selectedMember = member } } } - .sheet(item: $selectedMember, onDismiss: { + .appSheet(item: $selectedMember, onDismiss: { selectedMember = nil memberConnectionStats = nil }) { _ in diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 082888691d..090c11cbdd 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -240,7 +240,7 @@ struct ComposeView: View { CameraImageListPicker(images: $chosenImages) } } - .sheet(isPresented: $showImagePicker) { + .appSheet(isPresented: $showImagePicker) { LibraryImageListPicker(images: $chosenImages, selectionLimit: 10) { itemsSelected in showImagePicker = false if itemsSelected { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index a0bd2af656..1d155dd42d 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -78,10 +78,10 @@ struct GroupChatInfoView: View { } label: { memberView(member) } } } - .sheet(isPresented: $showAddMembersSheet) { + .appSheet(isPresented: $showAddMembersSheet) { AddGroupMembersView(chat: chat, groupInfo: groupInfo) } - .sheet(item: $selectedMember, onDismiss: { + .appSheet(item: $selectedMember, onDismiss: { selectedMember = nil connectionStats = nil }) { _ in diff --git a/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift b/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift index 32adf861f3..88c0f52e00 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift @@ -82,7 +82,7 @@ struct GroupProfileView: View { CameraImagePicker(image: $chosenImage) } } - .sheet(isPresented: $showImagePicker) { + .appSheet(isPresented: $showImagePicker) { LibraryImagePicker(image: $chosenImage) { didSelectItem in showImagePicker = false } diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift index a49789aeaa..1cd50c606d 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift @@ -66,7 +66,7 @@ struct ContactConnectionView: View { Spacer() } .frame(maxHeight: .infinity) - .sheet(isPresented: $showContactConnectionInfo) { + .appSheet(isPresented: $showContactConnectionInfo) { ContactConnectionInfo(contactConnection: contactConnection) } } diff --git a/apps/ios/Shared/Views/Helpers/AppSheet.swift b/apps/ios/Shared/Views/Helpers/AppSheet.swift new file mode 100644 index 0000000000..aa8bb4fce3 --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/AppSheet.swift @@ -0,0 +1,66 @@ +// +// AppSheet.swift +// SimpleX (iOS) +// +// Created by Evgeny on 24/11/2022. +// Copyright © 2022 SimpleX Chat. All rights reserved. +// + +import SwiftUI + +private struct SheetIsPresented: ViewModifier where C: View { + var isPresented: Binding + var onDismiss: (() -> Void)? + var sheetContent: () -> C + @Environment(\.scenePhase) var scenePhase + + func body(content: Content) -> some View { + content.sheet(isPresented: isPresented, onDismiss: onDismiss) { + sheetContent().modifier(PrivacySensitive()) + } + } +} + +private struct SheetForItem: ViewModifier where T: Identifiable, C: View { + var item: Binding + var onDismiss: (() -> Void)? + var sheetContent: (T) -> C + @Environment(\.scenePhase) var scenePhase + + func body(content: Content) -> some View { + content.sheet(item: item, onDismiss: onDismiss) { it in + sheetContent(it).modifier(PrivacySensitive()) + } + } +} + +private struct PrivacySensitive: ViewModifier { + @AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = true + @Environment(\.scenePhase) var scenePhase + + func body(content: Content) -> some View { + if case .active = scenePhase { + content + } else { + content.privacySensitive(protectScreen).redacted(reason: .privacy) + } + } +} + +extension View { + func appSheet( + isPresented: Binding, + onDismiss: (() -> Void)? = nil, + content: @escaping () -> Content + ) -> some View where Content: View { + modifier(SheetIsPresented(isPresented: isPresented, onDismiss: onDismiss, sheetContent: content)) + } + + func appSheet( + item: Binding, + onDismiss: (() -> Void)? = nil, + content: @escaping (T) -> Content + ) -> some View where T: Identifiable, Content: View { + modifier(SheetForItem(item: item, onDismiss: onDismiss, sheetContent: content)) + } +} diff --git a/apps/ios/Shared/Views/NewChat/AddGroupView.swift b/apps/ios/Shared/Views/NewChat/AddGroupView.swift index ed4e82c0e0..2f1491e77f 100644 --- a/apps/ios/Shared/Views/NewChat/AddGroupView.swift +++ b/apps/ios/Shared/Views/NewChat/AddGroupView.swift @@ -136,7 +136,7 @@ struct AddGroupView: View { CameraImagePicker(image: $chosenImage) } } - .sheet(isPresented: $showImagePicker) { + .appSheet(isPresented: $showImagePicker) { LibraryImagePicker(image: $chosenImage) { didSelectItem in showImagePicker = false } diff --git a/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift b/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift index cdd5f0ce94..d93cf81aa9 100644 --- a/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift +++ b/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift @@ -53,7 +53,7 @@ struct SimpleXInfo: View { .padding(.bottom, 8) .frame(maxWidth: .infinity) } - .sheet(isPresented: $showHowItWorks) { + .appSheet(isPresented: $showHowItWorks) { HowItWorks(onboarding: onboarding) } } diff --git a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift index 0f5ec43d6b..f49d6bdaff 100644 --- a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift +++ b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift @@ -15,12 +15,16 @@ struct PrivacySettings: View { @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @AppStorage(GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE, store: groupDefaults) private var transferImagesInline = false @State private var simplexLinkMode = privacySimplexLinkModeDefault.get() + @AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = true var body: some View { VStack { List { Section("Device") { SimplexLockSetting() + settingsRow("eye.slash") { + Toggle("Protect app screen", isOn: $protectScreen) + } } Section { diff --git a/apps/ios/Shared/Views/UserSettings/SMPServersView.swift b/apps/ios/Shared/Views/UserSettings/SMPServersView.swift index dbee66a643..66e807b886 100644 --- a/apps/ios/Shared/Views/UserSettings/SMPServersView.swift +++ b/apps/ios/Shared/Views/UserSettings/SMPServersView.swift @@ -79,7 +79,7 @@ struct SMPServersView: View { Button("Add preset servers", action: addAllPresets) .disabled(hasAllPresets()) } - .sheet(isPresented: $showScanSMPServer) { + .appSheet(isPresented: $showScanSMPServer) { ScanSMPServer(servers: $servers) } .alert(item: $alert) { a in diff --git a/apps/ios/Shared/Views/UserSettings/SettingsButton.swift b/apps/ios/Shared/Views/UserSettings/SettingsButton.swift index 7292fd4373..7e53fe29c7 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsButton.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsButton.swift @@ -16,7 +16,7 @@ struct SettingsButton: View { Button { showSettings = true } label: { Image(systemName: "gearshape") } - .sheet(isPresented: $showSettings, content: { + .appSheet(isPresented: $showSettings, content: { SettingsView(showSettings: $showSettings) }) } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index 91dabfbd1c..e2125b1e0c 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -24,6 +24,7 @@ let DEFAULT_WEBRTC_ICE_SERVERS = "webrtcICEServers" let DEFAULT_PRIVACY_ACCEPT_IMAGES = "privacyAcceptImages" let DEFAULT_PRIVACY_LINK_PREVIEWS = "privacyLinkPreviews" let DEFAULT_PRIVACY_SIMPLEX_LINK_MODE = "privacySimplexLinkMode" +let DEFAULT_PRIVACY_PROTECT_SCREEN = "privacyProtectScreen" let DEFAULT_EXPERIMENTAL_CALLS = "experimentalCalls" let DEFAULT_CHAT_ARCHIVE_NAME = "chatArchiveName" let DEFAULT_CHAT_ARCHIVE_TIME = "chatArchiveTime" @@ -45,6 +46,7 @@ let appDefaults: [String: Any] = [ DEFAULT_PRIVACY_ACCEPT_IMAGES: true, DEFAULT_PRIVACY_LINK_PREVIEWS: true, DEFAULT_PRIVACY_SIMPLEX_LINK_MODE: "description", + DEFAULT_PRIVACY_PROTECT_SCREEN: true, DEFAULT_EXPERIMENTAL_CALLS: false, DEFAULT_CHAT_V3_DB_MIGRATION: "offer", DEFAULT_DEVELOPER_TOOLS: false, diff --git a/apps/ios/Shared/Views/UserSettings/UserProfile.swift b/apps/ios/Shared/Views/UserSettings/UserProfile.swift index de7a19c8bd..ad275cf4d9 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfile.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfile.swift @@ -100,7 +100,7 @@ struct UserProfile: View { CameraImagePicker(image: $chosenImage) } } - .sheet(isPresented: $showImagePicker) { + .appSheet(isPresented: $showImagePicker) { LibraryImagePicker(image: $chosenImage) { didSelectItem in showImagePicker = false } 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 8cade88fcb..c9885b7b0b 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -1843,6 +1843,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Die Gruppe wurde nicht gefunden! 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 Keine empfangenen oder gesendeten Dateien @@ -1948,9 +1953,9 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Open-Source-Protokoll und -Code – Jede Person kann ihre eigenen Server aufsetzen und nutzen. No comment provided by engineer. - - Opening the link in the browser may reduce connection privacy and security. - ***Opening the link in the browser may reduce connection privacy and security. + + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + ***Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. No comment provided by engineer. @@ -2063,6 +2068,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v ***Prohibit sending voice messages. No comment provided by engineer. + + Protect app screen + ***Protect app screen + No comment provided by engineer. + Protocol timeout Protokollzeitüberschreitung @@ -2398,11 +2408,6 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v Vorschau anzeigen No comment provided by engineer. - - SimpleX one-time invitation - SimpleX Einmal-Link - simplex link type - SimpleX Lock SimpleX Sperre @@ -2433,6 +2438,11 @@ Wir werden Serverredundanzen hinzufügen, um verloren gegangene Nachrichten zu v ***SimpleX links No comment provided by engineer. + + SimpleX one-time invitation + SimpleX Einmal-Link + simplex link type + Skip Überspringen @@ -2690,6 +2700,11 @@ You will be prompted to complete authentication before this feature is enabled.< Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funktion aktiviert wird. No comment provided by engineer. + + To record voice message please grant permission to use Microphone. + ***To record voice message please grant permission to use Microphone. + No comment provided by engineer. + To support instant push notifications the chat database has to be migrated. Um sofortige Push-Benachrichtigungen zu unterstützen, muss die Chat-Datenbank migriert werden. @@ -2725,6 +2740,11 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt Einschalten No comment provided by engineer. + + Unable to record voice message + ***Unable to record voice message + No comment provided by engineer. + Unexpected error: %@ Unerwarteter Fehler: %@ 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 4b9b910046..29719bad86 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -1843,6 +1843,11 @@ We will be adding server redundancy to prevent lost messages. Group not found! 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 No received or sent files @@ -1948,9 +1953,9 @@ We will be adding server redundancy to prevent lost messages. Open-source protocol and code – anybody can run the servers. No comment provided by engineer. - - Opening the link in the browser may reduce connection privacy and security. - Opening the link in the browser may reduce connection privacy and security. + + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. No comment provided by engineer. @@ -2063,6 +2068,11 @@ We will be adding server redundancy to prevent lost messages. Prohibit sending voice messages. No comment provided by engineer. + + Protect app screen + Protect app screen + No comment provided by engineer. + Protocol timeout Protocol timeout @@ -2398,11 +2408,6 @@ We will be adding server redundancy to prevent lost messages. Show preview No comment provided by engineer. - - SimpleX one-time invitation - SimpleX one-time invitation - simplex link type - SimpleX Lock SimpleX Lock @@ -2433,6 +2438,11 @@ We will be adding server redundancy to prevent lost messages. SimpleX links No comment provided by engineer. + + SimpleX one-time invitation + SimpleX one-time invitation + simplex link type + Skip Skip @@ -2690,6 +2700,11 @@ You will be prompted to complete authentication before this feature is enabled.< You will be prompted to complete authentication before this feature is enabled. No comment provided by engineer. + + To record voice message please grant permission to use Microphone. + To record voice message please grant permission to use Microphone. + No comment provided by engineer. + To support instant push notifications the chat database has to be migrated. To support instant push notifications the chat database has to be migrated. @@ -2725,6 +2740,11 @@ You will be prompted to complete authentication before this feature is enabled.< Turn on No comment provided by engineer. + + Unable to record voice message + Unable to record voice message + No comment provided by engineer. + Unexpected error: %@ Unexpected error: %@ 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 91e1b7dcdf..3de49d3121 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -1843,6 +1843,11 @@ We will be adding server redundancy to prevent lost messages. Группа не найдена! No comment provided by engineer. + + No permission to record voice message + Нет разрешения для записи голосового сообщения + No comment provided by engineer. + No received or sent files Нет полученных или отправленных файлов @@ -1948,9 +1953,9 @@ We will be adding server redundancy to prevent lost messages. Открытый протокол и код - кто угодно может запустить сервер. No comment provided by engineer. - - Opening the link in the browser may reduce connection privacy and security. - Использование ссылки в браузере может уменьшить конфиденциальность и безопасность соединения. + + Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red. + Использование ссылки в браузере может уменьшить конфиденциальность и безопасность соединения. Ссылки на неизвестные сайты будут красными. No comment provided by engineer. @@ -2063,6 +2068,11 @@ We will be adding server redundancy to prevent lost messages. Запретить отправлять голосовые сообщений. No comment provided by engineer. + + Protect app screen + Защитить экран приложения + No comment provided by engineer. + Protocol timeout Таймаут протокола @@ -2398,11 +2408,6 @@ We will be adding server redundancy to prevent lost messages. Показывать уведомления No comment provided by engineer. - - SimpleX one-time invitation - SimpleX одноразовая ссылка - simplex link type - SimpleX Lock Блокировка SimpleX @@ -2433,6 +2438,11 @@ We will be adding server redundancy to prevent lost messages. SimpleX ссылки No comment provided by engineer. + + SimpleX one-time invitation + SimpleX одноразовая ссылка + simplex link type + Skip Пропустить @@ -2690,6 +2700,11 @@ You will be prompted to complete authentication before this feature is enabled.< Вам будет нужно пройти аутентификацию для включения блокировки. No comment provided by engineer. + + To record voice message please grant permission to use Microphone. + Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону. + No comment provided by engineer. + To support instant push notifications the chat database has to be migrated. Для поддержки мгновенный доставки уведомлений данные чата должны быть перемещены. @@ -2725,6 +2740,11 @@ You will be prompted to complete authentication before this feature is enabled.< Включить No comment provided by engineer. + + Unable to record voice message + Невозможно записать голосовое сообщение + No comment provided by engineer. + Unexpected error: %@ Неожиданная ошибка: %@ diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index c8a7b2e2d2..93c4616841 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -78,6 +78,7 @@ 5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */; }; 5CA059ED279559F40002BEB4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059C4279559F40002BEB4 /* ContentView.swift */; }; 5CA059EF279559F40002BEB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5CA059C5279559F40002BEB4 /* Assets.xcassets */; }; + 5CA7DFC329302AF000F7FDDE /* AppSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA7DFC229302AF000F7FDDE /* AppSheet.swift */; }; 5CADE79A29211BB900072E13 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CADE79929211BB900072E13 /* PreferencesView.swift */; }; 5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CADE79B292131E900072E13 /* ContactPreferencesView.swift */; }; 5CB0BA882826CB3A00B3292C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CB0BA862826CB3A00B3292C /* InfoPlist.strings */; }; @@ -287,6 +288,7 @@ 5CA059D7279559F40002BEB4 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOS.swift; sourceTree = ""; }; 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOSLaunchTests.swift; sourceTree = ""; }; + 5CA7DFC229302AF000F7FDDE /* AppSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSheet.swift; sourceTree = ""; }; 5CADE79929211BB900072E13 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; 5CADE79B292131E900072E13 /* ContactPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPreferencesView.swift; sourceTree = ""; }; 5CB0BA872826CB3A00B3292C /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -502,6 +504,7 @@ 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */, 5C6BA666289BD954009B8ECC /* DismissSheets.swift */, 5C00164328A26FBC0094D739 /* ContextMenu.swift */, + 5CA7DFC229302AF000F7FDDE /* AppSheet.swift */, ); path = Helpers; sourceTree = ""; @@ -956,6 +959,7 @@ 5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */, 5CB2085128DB64CA00D024EC /* CreateLinkView.swift in Sources */, 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */, + 5CA7DFC329302AF000F7FDDE /* AppSheet.swift in Sources */, 64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */, 5CC1C99227A6C7F5000D9FF6 /* QRCode.swift in Sources */, 5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */, diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings index e6a7c107fe..8985030031 100644 --- a/apps/ios/de.lproj/Localizable.strings +++ b/apps/ios/de.lproj/Localizable.strings @@ -1310,6 +1310,9 @@ /* No comment provided by engineer. */ "No group!" = "Die Gruppe wurde nicht gefunden!"; +/* 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" = "Keine empfangenen oder gesendeten Dateien"; @@ -1381,7 +1384,7 @@ "Open-source protocol and code – anybody can run the servers." = "Open-Source-Protokoll und -Code – Jede Person kann ihre eigenen Server aufsetzen und nutzen."; /* No comment provided by engineer. */ -"Opening the link in the browser may reduce connection privacy and security." = "***Opening the link in the browser may reduce connection privacy and security."; +"Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red." = "***Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red."; /* No comment provided by engineer. */ "or chat with the developers" = "oder chatten Sie mit den Entwicklern"; @@ -1458,6 +1461,9 @@ /* No comment provided by engineer. */ "Prohibit sending voice messages." = "***Prohibit sending voice messages."; +/* No comment provided by engineer. */ +"Protect app screen" = "***Protect app screen"; + /* No comment provided by engineer. */ "Protocol timeout" = "Protokollzeitüberschreitung"; @@ -1866,6 +1872,9 @@ /* No comment provided by engineer. */ "To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled." = "Um Ihre Informationen zu schützen, schalten Sie die SimpleX Sperre ein.\nSie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funktion aktiviert wird."; +/* No comment provided by engineer. */ +"To record voice message please grant permission to use Microphone." = "***To record voice message please grant permission to use Microphone."; + /* No comment provided by engineer. */ "To support instant push notifications the chat database has to be migrated." = "Um sofortige Push-Benachrichtigungen zu unterstützen, muss die Chat-Datenbank migriert werden."; @@ -1887,6 +1896,9 @@ /* No comment provided by engineer. */ "Turn on" = "Einschalten"; +/* No comment provided by engineer. */ +"Unable to record voice message" = "***Unable to record voice message"; + /* No comment provided by engineer. */ "Unexpected error: %@" = "Unerwarteter Fehler: %@"; diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings index 12d57fb830..06fd7a8fc9 100644 --- a/apps/ios/ru.lproj/Localizable.strings +++ b/apps/ios/ru.lproj/Localizable.strings @@ -1310,6 +1310,9 @@ /* No comment provided by engineer. */ "No group!" = "Группа не найдена!"; +/* No comment provided by engineer. */ +"No permission to record voice message" = "Нет разрешения на запись голоса"; + /* No comment provided by engineer. */ "No received or sent files" = "Нет полученных или отправленных файлов"; @@ -1381,7 +1384,7 @@ "Open-source protocol and code – anybody can run the servers." = "Открытый протокол и код - кто угодно может запустить сервер."; /* No comment provided by engineer. */ -"Opening the link in the browser may reduce connection privacy and security." = "Использование ссылки в браузере может уменьшить конфиденциальность и безопасность соединения."; +"Opening the link in the browser may reduce connection privacy and security. Untrusted SimpleX links will be red." = "Использование ссылки в браузере может уменьшить конфиденциальность и безопасность соединения. Ссылки на неизвестные сайты будут красными."; /* No comment provided by engineer. */ "or chat with the developers" = "или соединитесь с разработчиками"; @@ -1458,6 +1461,9 @@ /* No comment provided by engineer. */ "Prohibit sending voice messages." = "Запретить отправлять голосовые сообщений."; +/* No comment provided by engineer. */ +"Protect app screen" = "Защитить экран приложения"; + /* No comment provided by engineer. */ "Protocol timeout" = "Таймаут протокола"; @@ -1866,6 +1872,9 @@ /* No comment provided by engineer. */ "To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled." = "Чтобы защитить вашу информацию, включите блокировку SimpleX Chat.\nВам будет нужно пройти аутентификацию для включения блокировки."; +/* No comment provided by engineer. */ +"To record voice message please grant permission to use Microphone." = "Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону."; + /* No comment provided by engineer. */ "To support instant push notifications the chat database has to be migrated." = "Для поддержки мгновенный доставки уведомлений данные чата должны быть перемещены."; @@ -1887,6 +1896,9 @@ /* No comment provided by engineer. */ "Turn on" = "Включить"; +/* No comment provided by engineer. */ +"Unable to record voice message" = "Невозможно записать голосовое сообщение"; + /* No comment provided by engineer. */ "Unexpected error: %@" = "Неожиданная ошибка: %@"; diff --git a/apps/ios/ru.lproj/SimpleX--iOS--InfoPlist.strings b/apps/ios/ru.lproj/SimpleX--iOS--InfoPlist.strings index 85a0405435..3cd5a3cab0 100644 --- a/apps/ios/ru.lproj/SimpleX--iOS--InfoPlist.strings +++ b/apps/ios/ru.lproj/SimpleX--iOS--InfoPlist.strings @@ -8,7 +8,7 @@ "NSFaceIDUsageDescription" = "SimpleX использует Face ID для аутентификации"; /* Privacy - Microphone Usage Description */ -"NSMicrophoneUsageDescription" = "SimpleX использует микрофон для аудио и видео звонков."; +"NSMicrophoneUsageDescription" = "SimpleX использует микрофон для аудио и видео звонков, и для записи голосовых сообщений."; /* Privacy - Photo Library Additions Usage Description */ "NSPhotoLibraryAddUsageDescription" = "SimpleX использует доступ к Photo Library для сохранения сделанных и полученных фотографий";