From c934415355f76280b2f437ceddf476bb3f60184a Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Thu, 3 Nov 2022 17:26:10 +1100 Subject: [PATCH 1/4] General bug fixing Fixed an issue where the database could get suspended if the app is launched when the app is doing a background fetch Fixed an incorrectly localized string Fixed an issue where the author name on a message didn't have it's width constrained Fixed a bug where the conversation message list inset wasn't getting updated properly in some cases Tweaked some logic in the OpenGroupPoller when running from the background to try and close some of the odd cases --- Session.xcodeproj/project.pbxproj | 24 +++++++++---------- Session/Closed Groups/EditClosedGroupVC.swift | 2 +- Session/Conversations/ConversationVC.swift | 20 +++++++++------- .../Message Cells/VisibleMessageCell.swift | 2 ++ Session/Meta/AppDelegate.swift | 12 ++++++---- .../Pollers/OpenGroupPoller.swift | 14 ++++++++--- 6 files changed, 45 insertions(+), 29 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 642093112..ea42d0fbb 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -6032,7 +6032,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6057,7 +6057,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6105,7 +6105,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6135,7 +6135,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6171,7 +6171,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6194,7 +6194,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -6245,7 +6245,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6273,7 +6273,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -7173,7 +7173,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7212,7 +7212,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; @@ -7245,7 +7245,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 385; + CURRENT_PROJECT_VERSION = 386; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7284,7 +7284,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_NAME = Session; diff --git a/Session/Closed Groups/EditClosedGroupVC.swift b/Session/Closed Groups/EditClosedGroupVC.swift index 42c150a15..3c1ef4444 100644 --- a/Session/Closed Groups/EditClosedGroupVC.swift +++ b/Session/Closed Groups/EditClosedGroupVC.swift @@ -314,7 +314,7 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat .trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) guard !updatedName.isEmpty else { - return showError(title: "vc_create_closed_group_group_name_missing_error".lowercased()) + return showError(title: "vc_create_closed_group_group_name_missing_error".localized()) } guard updatedName.count < 64 else { return showError(title: "vc_create_closed_group_group_name_too_long_error".localized()) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 8bb622e84..f342c6824 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -54,9 +54,10 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl var scrollDistanceToBottomBeforeUpdate: CGFloat? var baselineKeyboardHeight: CGFloat = 0 - /// This flag is true between `viewDidAppear` and `viewWillDisappear` and is used to prevent keyboard changes - /// from trying to animate (as the animations can cause staggering with push transitions) - var viewIsFocussed = false + /// These flags are true between `viewDid/Will Appear/Disappear` and is used to prevent keyboard changes + /// from trying to animate (as the animations can cause buggy transitions) + var viewIsDisappearing = false + var viewIsAppearing = false // Reaction var currentReactionListSheet: ReactionListSheet? @@ -399,6 +400,8 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl super.viewWillAppear(animated) startObservingChanges() + + viewIsAppearing = true } override func viewDidAppear(_ animated: Bool) { @@ -407,7 +410,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl // Flag that the initial layout has been completed (the flag blocks and unblocks a number // of different behaviours) didFinishInitialLayout = true - viewIsFocussed = true + viewIsAppearing = false if delayFirstResponder || isShowingSearchUI { delayFirstResponder = false @@ -426,7 +429,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - viewIsFocussed = false + viewIsDisappearing = true // Don't set the draft or resign the first responder if we are replacing the thread (want the keyboard // to appear to remain focussed) @@ -442,6 +445,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl mediaCache.removeAllObjects() hasReloadedThreadDataAfterDisappearance = false + viewIsDisappearing = false } @objc func applicationDidBecomeActive(_ notification: Notification) { @@ -1067,7 +1071,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl // MARK: - Notifications @objc func handleKeyboardWillChangeFrameNotification(_ notification: Notification) { - guard viewIsFocussed || !didFinishInitialLayout else { return } + guard !viewIsDisappearing else { return } // Please refer to https://github.com/mapbox/mapbox-navigation-ios/issues/1600 // and https://stackoverflow.com/a/25260930 to better understand what we are @@ -1115,7 +1119,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl } // Perform the changes (don't animate if the initial layout hasn't been completed) - guard hasDoneLayout && didFinishInitialLayout else { + guard hasDoneLayout && didFinishInitialLayout && !viewIsAppearing else { UIView.performWithoutAnimation { changes() } @@ -1132,8 +1136,6 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl } @objc func handleKeyboardWillHideNotification(_ notification: Notification) { - guard viewIsFocussed else { return } - // Please refer to https://github.com/mapbox/mapbox-navigation-ios/issues/1600 // and https://stackoverflow.com/a/25260930 to better understand what we are // doing with the UIViewAnimationOptions diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 84e3004ed..442a7e9aa 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -227,6 +227,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { // Remaining constraints authorLabel.pin(.leading, to: .leading, of: snContentView, withInset: VisibleMessageCell.authorLabelInset) + authorLabel.pin(.trailing, to: .trailing, of: self, withInset: -Values.mediumSpacing) // Under bubble content addSubview(underBubbleStackView) @@ -1052,6 +1053,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { ) -> TappableLabel { let isOutgoing: Bool = (cellViewModel.variant == .standardOutgoing) let result: TappableLabel = TappableLabel() + result.setContentCompressionResistancePriority(.required, for: .vertical) result.themeBackgroundColor = .clear result.isOpaque = false result.isUserInteractionEnabled = true diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index b2a97dfe4..12a5b6b83 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -214,8 +214,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD BackgroundPoller.isValid = false - // Suspend database - NotificationCenter.default.post(name: Database.suspendNotification, object: self) + if CurrentAppContext().isInBackground() { + // Suspend database + NotificationCenter.default.post(name: Database.suspendNotification, object: self) + } SNLog("Background poll failed due to manual timeout") completionHandler(.failed) @@ -233,8 +235,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD BackgroundPoller.isValid = false - // Suspend database - NotificationCenter.default.post(name: Database.suspendNotification, object: self) + if CurrentAppContext().isInBackground() { + // Suspend database + NotificationCenter.default.post(name: Database.suspendNotification, object: self) + } cancelTimer.invalidate() completionHandler(result) diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift index 0166e026c..6bb65315d 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift @@ -84,7 +84,7 @@ extension OpenGroupAPI { let (promise, seal) = Promise.pending() promise.retainUntilComplete() - Threading.pollerQueue.async { + let pollingLogic: () -> Void = { dependencies.storage .read { db -> Promise<(Int64, PollResponse)> in let failureCount: Int64 = (try? OpenGroup @@ -150,7 +150,7 @@ extension OpenGroupAPI { error: error ) .done(on: OpenGroupAPI.workQueue) { [weak self] didHandleError in - if !didHandleError { + if !didHandleError && isBackgroundPollerValid() { // Increase the failure count let pollFailureCount: Int64 = Storage.shared .read { db in @@ -181,6 +181,14 @@ extension OpenGroupAPI { } } + // If this was run via the background poller then don't run on the pollerQueue + if calledFromBackgroundPoller { + pollingLogic() + } + else { + Threading.pollerQueue.async { pollingLogic() } + } + return promise } @@ -217,7 +225,7 @@ extension OpenGroupAPI { ) } .then(on: OpenGroupAPI.workQueue) { [weak self] _, responseBody -> Promise in - guard let strongSelf = self else { return Promise.value(()) } + guard let strongSelf = self, isBackgroundPollerValid() else { return Promise.value(()) } // Handle the updated capabilities and re-trigger the poll strongSelf.isPolling = false From f4d4e7d81092e363f4232a1cd70096ae42205ebf Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 7 Nov 2022 10:18:59 +1100 Subject: [PATCH 2/4] Fixed an issue with blinding being switched on Fixed an issue where a user that was part of an open group before blinding was enabled wouldn't be able to access the group once blinding was switched on Updated the code to better support errors sent from SOGS as bencoded data --- .../Open Groups/OpenGroupAPI.swift | 11 ++- .../Models/OnionRequestAPIError.swift | 3 + SessionSnodeKit/OnionRequestAPI.swift | 98 +++++++++++-------- 3 files changed, 67 insertions(+), 45 deletions(-) diff --git a/SessionMessagingKit/Open Groups/OpenGroupAPI.swift b/SessionMessagingKit/Open Groups/OpenGroupAPI.swift index 4d32c974b..051ba7cc2 100644 --- a/SessionMessagingKit/Open Groups/OpenGroupAPI.swift +++ b/SessionMessagingKit/Open Groups/OpenGroupAPI.swift @@ -227,6 +227,7 @@ public enum OpenGroupAPI { public static func capabilities( _ db: Database, server: String, + forceBlinded: Bool = false, using dependencies: SMKDependencies = SMKDependencies() ) -> Promise<(OnionRequestResponseInfoType, Capabilities)> { return OpenGroupAPI @@ -236,6 +237,7 @@ public enum OpenGroupAPI { server: server, endpoint: .capabilities ), + forceBlinded: forceBlinded, using: dependencies ) .decoded(as: Capabilities.self, on: OpenGroupAPI.workQueue, using: dependencies) @@ -1260,6 +1262,7 @@ public enum OpenGroupAPI { messageBytes: Bytes, for serverName: String, fallbackSigningType signingType: SessionId.Prefix, + forceBlinded: Bool = false, using dependencies: SMKDependencies = SMKDependencies() ) -> (publicKey: String, signature: Bytes)? { guard @@ -1279,7 +1282,7 @@ public enum OpenGroupAPI { .defaulting(to: []) // If we have no capabilities or if the server supports blinded keys then sign using the blinded key - if capabilities.isEmpty || capabilities.contains(.blind) { + if forceBlinded || capabilities.isEmpty || capabilities.contains(.blind) { guard let blindedKeyPair: Box.KeyPair = dependencies.sodium.blindedKeyPair(serverPublicKey: serverPublicKey, edKeyPair: userEdKeyPair, genericHash: dependencies.genericHash) else { return nil } @@ -1326,6 +1329,7 @@ public enum OpenGroupAPI { request: URLRequest, for serverName: String, with serverPublicKey: String, + forceBlinded: Bool = false, using dependencies: SMKDependencies = SMKDependencies() ) -> URLRequest? { guard let url: URL = request.url else { return nil } @@ -1366,7 +1370,7 @@ public enum OpenGroupAPI { .appending(contentsOf: bodyHash ?? []) /// Sign the above message - guard let signResult: (publicKey: String, signature: Bytes) = sign(db, messageBytes: messageBytes, for: serverName, fallbackSigningType: .unblinded, using: dependencies) else { + guard let signResult: (publicKey: String, signature: Bytes) = sign(db, messageBytes: messageBytes, for: serverName, fallbackSigningType: .unblinded, forceBlinded: forceBlinded, using: dependencies) else { return nil } @@ -1386,6 +1390,7 @@ public enum OpenGroupAPI { private static func send( _ db: Database, request: Request, + forceBlinded: Bool = false, using dependencies: SMKDependencies = SMKDependencies() ) -> Promise<(OnionRequestResponseInfoType, Data?)> { let urlRequest: URLRequest @@ -1406,7 +1411,7 @@ public enum OpenGroupAPI { guard let publicKey: String = maybePublicKey else { return Promise(error: OpenGroupAPIError.noPublicKey) } // Attempt to sign the request with the new auth - guard let signedRequest: URLRequest = sign(db, request: urlRequest, for: request.server, with: publicKey, using: dependencies) else { + guard let signedRequest: URLRequest = sign(db, request: urlRequest, for: request.server, with: publicKey, forceBlinded: forceBlinded, using: dependencies) else { return Promise(error: OpenGroupAPIError.signingFailed) } diff --git a/SessionSnodeKit/Models/OnionRequestAPIError.swift b/SessionSnodeKit/Models/OnionRequestAPIError.swift index 3b75fe124..43e70da73 100644 --- a/SessionSnodeKit/Models/OnionRequestAPIError.swift +++ b/SessionSnodeKit/Models/OnionRequestAPIError.swift @@ -16,6 +16,9 @@ public enum OnionRequestAPIError: LocalizedError { switch self { case .httpRequestFailedAtDestination(let statusCode, let data, let destination): if statusCode == 429 { return "Rate limited." } + if let processedResponseBodyData: Data = OnionRequestAPI.process(bencodedData: data)?.body, let errorResponse: String = String(data: processedResponseBodyData, encoding: .utf8) { + return "HTTP request failed at destination (\(destination)) with status code: \(statusCode), error body: \(errorResponse)." + } if let errorResponse: String = String(data: data, encoding: .utf8) { return "HTTP request failed at destination (\(destination)) with status code: \(statusCode), error body: \(errorResponse)." } diff --git a/SessionSnodeKit/OnionRequestAPI.swift b/SessionSnodeKit/OnionRequestAPI.swift index 5a7e2fd45..d2a71b66c 100644 --- a/SessionSnodeKit/OnionRequestAPI.swift +++ b/SessionSnodeKit/OnionRequestAPI.swift @@ -700,72 +700,86 @@ public enum OnionRequestAPI: OnionRequestAPIType { do { let data: Data = try AESGCM.decrypt(responseData, with: destinationSymmetricKey) - // The data will be in the form of `l123:jsone` or `l123:json456:bodye` so we need to break the data into - // parts to properly process it - guard let responseString: String = String(data: data, encoding: .ascii), responseString.starts(with: "l") else { - return seal.reject(HTTP.Error.invalidResponse) - } - - let stringParts: [String.SubSequence] = responseString.split(separator: ":") - - guard stringParts.count > 1, let infoLength: Int = Int(stringParts[0].suffix(from: stringParts[0].index(stringParts[0].startIndex, offsetBy: 1))) else { - return seal.reject(HTTP.Error.invalidResponse) - } - - let infoStringStartIndex: String.Index = responseString.index(responseString.startIndex, offsetBy: "l\(infoLength):".count) - let infoStringEndIndex: String.Index = responseString.index(infoStringStartIndex, offsetBy: infoLength) - let infoString: String = String(responseString[infoStringStartIndex.. "l\(infoLength)\(infoString)e".count else { - return seal.fulfill((responseInfo, nil)) - } - - // Extract the response data as well - let dataString: String = String(responseString.suffix(from: infoStringEndIndex)) - let dataStringParts: [String.SubSequence] = dataString.split(separator: ":") - - guard dataStringParts.count > 1, let finalDataLength: Int = Int(dataStringParts[0]), let suffixData: Data = "e".data(using: .utf8) else { - return seal.reject(HTTP.Error.invalidResponse) - } - - let dataBytes: Array = Array(data) - let dataEndIndex: Int = (dataBytes.count - suffixData.count) - let dataStartIndex: Int = (dataEndIndex - finalDataLength) - let finalDataBytes: ArraySlice = dataBytes[dataStartIndex.. (info: ResponseInfo, body: Data?)? { + // The data will be in the form of `l123:jsone` or `l123:json456:bodye` so we need to break the data + // into parts to properly process it + guard let responseString: String = String(data: data, encoding: .ascii), responseString.starts(with: "l") else { + return nil + } + + let stringParts: [String.SubSequence] = responseString.split(separator: ":") + + guard stringParts.count > 1, let infoLength: Int = Int(stringParts[0].suffix(from: stringParts[0].index(stringParts[0].startIndex, offsetBy: 1))) else { + return nil + } + + let infoStringStartIndex: String.Index = responseString.index(responseString.startIndex, offsetBy: "l\(infoLength):".count) + let infoStringEndIndex: String.Index = responseString.index(infoStringStartIndex, offsetBy: infoLength) + let infoString: String = String(responseString[infoStringStartIndex.. "l\(infoLength)\(infoString)e".count else { + return (responseInfo, nil) + } + + // Extract the response data as well + let dataString: String = String(responseString.suffix(from: infoStringEndIndex)) + let dataStringParts: [String.SubSequence] = dataString.split(separator: ":") + + guard dataStringParts.count > 1, let finalDataLength: Int = Int(dataStringParts[0]), let suffixData: Data = "e".data(using: .utf8) else { + return nil + } + + let dataBytes: Array = Array(data) + let dataEndIndex: Int = (dataBytes.count - suffixData.count) + let dataStartIndex: Int = (dataEndIndex - finalDataLength) + let finalDataBytes: ArraySlice = dataBytes[dataStartIndex.. Date: Mon, 7 Nov 2022 10:19:17 +1100 Subject: [PATCH 3/4] Actually setting the 'forceBlinded' flag --- .../Sending & Receiving/Pollers/OpenGroupPoller.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift index 6bb65315d..48b8c0dff 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPoller.swift @@ -221,6 +221,7 @@ extension OpenGroupAPI { OpenGroupAPI.capabilities( db, server: server, + forceBlinded: true, using: dependencies ) } From d740fe32c253de88be0c591cd99e7bdacafc1974 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 8 Nov 2022 09:35:27 +1100 Subject: [PATCH 4/4] Added some copy to explain disabled buttons for message requests --- Session.xcodeproj/project.pbxproj | 12 ++-- Session/Conversations/ConversationVC.swift | 61 +++++++++++++++++-- .../Translations/de.lproj/Localizable.strings | 1 + .../Translations/en.lproj/Localizable.strings | 1 + .../Translations/es.lproj/Localizable.strings | 1 + .../Translations/fa.lproj/Localizable.strings | 1 + .../Translations/fi.lproj/Localizable.strings | 1 + .../Translations/fr.lproj/Localizable.strings | 1 + .../Translations/hi.lproj/Localizable.strings | 1 + .../Translations/hr.lproj/Localizable.strings | 1 + .../id-ID.lproj/Localizable.strings | 1 + .../Translations/it.lproj/Localizable.strings | 1 + .../Translations/ja.lproj/Localizable.strings | 1 + .../Translations/nl.lproj/Localizable.strings | 1 + .../Translations/pl.lproj/Localizable.strings | 1 + .../pt_BR.lproj/Localizable.strings | 1 + .../Translations/ru.lproj/Localizable.strings | 1 + .../Translations/si.lproj/Localizable.strings | 1 + .../Translations/sk.lproj/Localizable.strings | 1 + .../Translations/sv.lproj/Localizable.strings | 1 + .../Translations/th.lproj/Localizable.strings | 1 + .../vi-VN.lproj/Localizable.strings | 1 + .../zh-Hant.lproj/Localizable.strings | 1 + .../zh_CN.lproj/Localizable.strings | 1 + 24 files changed, 84 insertions(+), 11 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index ea42d0fbb..3b89e7edc 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -6032,7 +6032,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6105,7 +6105,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6171,7 +6171,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6245,7 +6245,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -7173,7 +7173,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7245,7 +7245,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 386; + CURRENT_PROJECT_VERSION = 387; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index f342c6824..e05b70794 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -29,6 +29,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl var shouldHighlightNextScrollToInteraction: Bool = false var scrollButtonBottomConstraint: NSLayoutConstraint? var scrollButtonMessageRequestsBottomConstraint: NSLayoutConstraint? + var scrollButtonPendingMessageRequestInfoBottomConstraint: NSLayoutConstraint? var messageRequestsViewBotomConstraint: NSLayoutConstraint? // Search @@ -235,7 +236,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl result.text = "MESSAGE_REQUESTS_INFO".localized() result.themeTextColor = .textSecondary result.textAlignment = .center - result.numberOfLines = 2 + result.numberOfLines = 0 return result }() @@ -269,6 +270,23 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl return result }() + + private lazy var pendingMessageRequestExplanationLabel: UILabel = { + let result: UILabel = UILabel() + result.translatesAutoresizingMaskIntoConstraints = false + result.setContentCompressionResistancePriority(.required, for: .vertical) + result.font = UIFont.systemFont(ofSize: 12) + result.text = "MESSAGE_REQUEST_PENDING_APPROVAL_INFO".localized() + result.themeTextColor = .textSecondary + result.textAlignment = .center + result.numberOfLines = 0 + result.isHidden = ( + !self.messageRequestView.isHidden || + self.viewModel.threadData.threadRequiresApproval == false + ) + + return result + }() // MARK: - Settings @@ -323,6 +341,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl // Message requests view & scroll to bottom view.addSubview(scrollButton) view.addSubview(messageRequestView) + view.addSubview(pendingMessageRequestExplanationLabel) messageRequestView.addSubview(messageRequestBlockButton) messageRequestView.addSubview(messageRequestDescriptionLabel) @@ -336,6 +355,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl self.scrollButtonBottomConstraint = scrollButton.pin(.bottom, to: .bottom, of: view, withInset: -16) self.scrollButtonBottomConstraint?.isActive = false // Note: Need to disable this to avoid a conflict with the other bottom constraint self.scrollButtonMessageRequestsBottomConstraint = scrollButton.pin(.bottom, to: .top, of: messageRequestView, withInset: -16) + self.scrollButtonPendingMessageRequestInfoBottomConstraint = scrollButton.pin(.bottom, to: .top, of: pendingMessageRequestExplanationLabel, withInset: -16) messageRequestBlockButton.pin(.top, to: .top, of: messageRequestView, withInset: 10) messageRequestBlockButton.center(.horizontal, in: messageRequestView) @@ -353,6 +373,10 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl messageRequestDeleteButton.pin(.right, to: .right, of: messageRequestView, withInset: -20) messageRequestDeleteButton.pin(.bottom, to: .bottom, of: messageRequestView) messageRequestDeleteButton.set(.width, to: .width, of: messageRequestAcceptButton) + + pendingMessageRequestExplanationLabel.pin(.left, to: .left, of: messageRequestView, withInset: 40) + pendingMessageRequestExplanationLabel.pin(.right, to: .right, of: messageRequestView, withInset: -40) + pendingMessageRequestExplanationLabel.pin(.bottom, to: .bottom, of: messageRequestView, withInset: -16) // Unread count view view.addSubview(unreadCountView) @@ -580,18 +604,34 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl { updateNavBarButtons(threadData: updatedThreadData, initialVariant: viewModel.initialThreadVariant) - let messageRequestsViewWasVisible: Bool = (messageRequestView.isHidden == false) + let messageRequestsViewWasVisible: Bool = ( + messageRequestView.isHidden == false + ) + let pendingMessageRequestInfoWasVisible: Bool = ( + pendingMessageRequestExplanationLabel.isHidden == false + ) UIView.animate(withDuration: 0.3) { [weak self] in self?.messageRequestView.isHidden = ( updatedThreadData.threadIsMessageRequest == false || updatedThreadData.threadRequiresApproval == true ) + self?.pendingMessageRequestExplanationLabel.isHidden = ( + self?.messageRequestView.isHidden == false || + updatedThreadData.threadRequiresApproval == false + ) self?.scrollButtonMessageRequestsBottomConstraint?.isActive = ( - updatedThreadData.threadIsMessageRequest == true + self?.messageRequestView.isHidden == false + ) + self?.scrollButtonPendingMessageRequestInfoBottomConstraint?.isActive = ( + self?.scrollButtonPendingMessageRequestInfoBottomConstraint?.isActive == false && + self?.pendingMessageRequestExplanationLabel.isHidden == false + ) + self?.scrollButtonBottomConstraint?.isActive = ( + self?.scrollButtonMessageRequestsBottomConstraint?.isActive == false && + self?.scrollButtonPendingMessageRequestInfoBottomConstraint?.isActive == false ) - self?.scrollButtonBottomConstraint?.isActive = (updatedThreadData.threadIsMessageRequest == false) // Update the table content inset and offset to account for // the dissapearance of the messageRequestsView @@ -605,6 +645,16 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl trailing: 0 ) } + else if pendingMessageRequestInfoWasVisible { + let messageRequestsOffset: CGFloat = ((self?.pendingMessageRequestExplanationLabel.bounds.height ?? 0) + (16 * 2)) + let oldContentInset: UIEdgeInsets = (self?.tableView.contentInset ?? UIEdgeInsets.zero) + self?.tableView.contentInset = UIEdgeInsets( + top: 0, + leading: 0, + bottom: max(oldContentInset.bottom - messageRequestsOffset, 0), + trailing: 0 + ) + } } } @@ -1096,11 +1146,12 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl let keyboardTop = (UIScreen.main.bounds.height - keyboardRect.minY) let messageRequestsOffset: CGFloat = (messageRequestView.isHidden ? 0 : messageRequestView.bounds.height + 16) + let pendingMessageRequestsOffset: CGFloat = (pendingMessageRequestExplanationLabel.isHidden ? 0 : (pendingMessageRequestExplanationLabel.bounds.height + (16 * 2))) let oldContentInset: UIEdgeInsets = tableView.contentInset let newContentInset: UIEdgeInsets = UIEdgeInsets( top: 0, leading: 0, - bottom: (Values.mediumSpacing + keyboardTop + messageRequestsOffset), + bottom: (Values.mediumSpacing + keyboardTop + messageRequestsOffset + pendingMessageRequestsOffset), trailing: 0 ) let newContentOffsetY: CGFloat = (tableView.contentOffset.y + (newContentInset.bottom - oldContentInset.bottom)) diff --git a/Session/Meta/Translations/de.lproj/Localizable.strings b/Session/Meta/Translations/de.lproj/Localizable.strings index 4d4bc9477..0088b2bec 100644 --- a/Session/Meta/Translations/de.lproj/Localizable.strings +++ b/Session/Meta/Translations/de.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/en.lproj/Localizable.strings b/Session/Meta/Translations/en.lproj/Localizable.strings index 841705dd8..58ae00a85 100644 --- a/Session/Meta/Translations/en.lproj/Localizable.strings +++ b/Session/Meta/Translations/en.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/es.lproj/Localizable.strings b/Session/Meta/Translations/es.lproj/Localizable.strings index e29f7cc97..c85047355 100644 --- a/Session/Meta/Translations/es.lproj/Localizable.strings +++ b/Session/Meta/Translations/es.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/fa.lproj/Localizable.strings b/Session/Meta/Translations/fa.lproj/Localizable.strings index a81e8044e..fc7608274 100644 --- a/Session/Meta/Translations/fa.lproj/Localizable.strings +++ b/Session/Meta/Translations/fa.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ ناپدید‌شدن پیام ها را خاموش کرده است"; "MESSAGE_STATE_READ" = "خوانده شد"; "MESSAGE_STATE_SENT" = "ارسال شد"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/fi.lproj/Localizable.strings b/Session/Meta/Translations/fi.lproj/Localizable.strings index 1d7e90341..4ff458bd0 100644 --- a/Session/Meta/Translations/fi.lproj/Localizable.strings +++ b/Session/Meta/Translations/fi.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/fr.lproj/Localizable.strings b/Session/Meta/Translations/fr.lproj/Localizable.strings index e7fb9d015..881482017 100644 --- a/Session/Meta/Translations/fr.lproj/Localizable.strings +++ b/Session/Meta/Translations/fr.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/hi.lproj/Localizable.strings b/Session/Meta/Translations/hi.lproj/Localizable.strings index 8d6ede90a..1cf729168 100644 --- a/Session/Meta/Translations/hi.lproj/Localizable.strings +++ b/Session/Meta/Translations/hi.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/hr.lproj/Localizable.strings b/Session/Meta/Translations/hr.lproj/Localizable.strings index 0deac1b06..39fd0eda0 100644 --- a/Session/Meta/Translations/hr.lproj/Localizable.strings +++ b/Session/Meta/Translations/hr.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/id-ID.lproj/Localizable.strings b/Session/Meta/Translations/id-ID.lproj/Localizable.strings index 22277ac92..60468ace4 100644 --- a/Session/Meta/Translations/id-ID.lproj/Localizable.strings +++ b/Session/Meta/Translations/id-ID.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/it.lproj/Localizable.strings b/Session/Meta/Translations/it.lproj/Localizable.strings index eaa08769a..b528d3110 100644 --- a/Session/Meta/Translations/it.lproj/Localizable.strings +++ b/Session/Meta/Translations/it.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/ja.lproj/Localizable.strings b/Session/Meta/Translations/ja.lproj/Localizable.strings index 3aac5b031..f7933ef8d 100644 --- a/Session/Meta/Translations/ja.lproj/Localizable.strings +++ b/Session/Meta/Translations/ja.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/nl.lproj/Localizable.strings b/Session/Meta/Translations/nl.lproj/Localizable.strings index ab67ea5f0..38b5e5143 100644 --- a/Session/Meta/Translations/nl.lproj/Localizable.strings +++ b/Session/Meta/Translations/nl.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/pl.lproj/Localizable.strings b/Session/Meta/Translations/pl.lproj/Localizable.strings index 1c279d400..2c1ea7e14 100644 --- a/Session/Meta/Translations/pl.lproj/Localizable.strings +++ b/Session/Meta/Translations/pl.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings index 014c097a2..1235bc38e 100644 --- a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings +++ b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/ru.lproj/Localizable.strings b/Session/Meta/Translations/ru.lproj/Localizable.strings index 3358177c0..737d22897 100644 --- a/Session/Meta/Translations/ru.lproj/Localizable.strings +++ b/Session/Meta/Translations/ru.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/si.lproj/Localizable.strings b/Session/Meta/Translations/si.lproj/Localizable.strings index 0e8aaed9f..0e3bdae28 100644 --- a/Session/Meta/Translations/si.lproj/Localizable.strings +++ b/Session/Meta/Translations/si.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/sk.lproj/Localizable.strings b/Session/Meta/Translations/sk.lproj/Localizable.strings index 94949bd9e..58db95bb6 100644 --- a/Session/Meta/Translations/sk.lproj/Localizable.strings +++ b/Session/Meta/Translations/sk.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/sv.lproj/Localizable.strings b/Session/Meta/Translations/sv.lproj/Localizable.strings index 85dabb086..beaf86ca9 100644 --- a/Session/Meta/Translations/sv.lproj/Localizable.strings +++ b/Session/Meta/Translations/sv.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/th.lproj/Localizable.strings b/Session/Meta/Translations/th.lproj/Localizable.strings index f0ffc0536..9df4d727c 100644 --- a/Session/Meta/Translations/th.lproj/Localizable.strings +++ b/Session/Meta/Translations/th.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings index 871a9255c..8045dc6c3 100644 --- a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings +++ b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings index 4fc986755..44d3ce9a2 100644 --- a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request"; diff --git a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings index 0dda67f24..a1374b94f 100644 --- a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings @@ -593,3 +593,4 @@ "DISAPPERING_MESSAGES_INFO_DISABLE" = "%@ has turned off disappearing messages"; "MESSAGE_STATE_READ" = "Read"; "MESSAGE_STATE_SENT" = "Sent"; +"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";