From 53a4dff9ddd18ca258d9bf20f1e9e27c5f340aed Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 18 May 2021 16:42:08 +1000 Subject: [PATCH 01/10] fix move-insert conflict --- Session/Home/HomeVC.swift | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 20a70778f..2808e224f 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -226,12 +226,26 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv switch rowChange.type { case .delete: tableView.deleteRows(at: [ rowChange.indexPath! ], with: UITableView.RowAnimation.automatic) case .insert: tableView.insertRows(at: [ rowChange.newIndexPath! ], with: UITableView.RowAnimation.automatic) - case .move: tableView.moveRow(at: rowChange.indexPath!, to: rowChange.newIndexPath!) case .update: tableView.reloadRows(at: [ rowChange.indexPath! ], with: UITableView.RowAnimation.automatic) default: break } } tableView.endUpdates() + // HACK: Moves can have conflicts with other 3 types of change. + // Just batch perform all the moves seperately to prevent crashing. + // Since all the changes are from original state to final state, + // it will still be correct if we pick the Moves out. + tableView.beginUpdates() + rowChanges.forEach { rowChange in + let rowChange = rowChange as! YapDatabaseViewRowChange + let key = rowChange.collectionKey.key + threadViewModelCache[key] = nil + switch rowChange.type { + case .move: tableView.moveRow(at: rowChange.indexPath!, to: rowChange.newIndexPath!) + default: break + } + } + tableView.endUpdates() emptyStateView.isHidden = (threadCount != 0) } From c36cf1a36d1fb1ccea7da5acc2846854854a0c8d Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 19 May 2021 08:42:58 +1000 Subject: [PATCH 02/10] Hopefully fix closed group handling bug --- Session/Utilities/BackgroundPoller.swift | 2 +- .../Sending & Receiving/MessageReceiver.swift | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Session/Utilities/BackgroundPoller.swift b/Session/Utilities/BackgroundPoller.swift index d16570ae1..4ce1f8147 100644 --- a/Session/Utilities/BackgroundPoller.swift +++ b/Session/Utilities/BackgroundPoller.swift @@ -43,7 +43,7 @@ public final class BackgroundPoller : NSObject { } private static func getMessages(for publicKey: String) -> Promise { - return SnodeAPI.getSwarm(for: publicKey).then2 { swarm -> Promise in + return SnodeAPI.getSwarm(for: publicKey).then(on: DispatchQueue.main) { swarm -> Promise in guard let snode = swarm.randomElement() else { throw SnodeAPI.Error.generic } return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise in let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey) diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index cf724fe9f..8e6e53bca 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -54,11 +54,6 @@ public enum MessageReceiver { // Parse the envelope let envelope = try SNProtoEnvelope.parseData(data) let storage = SNMessagingKitConfiguration.shared.storage - // If the message failed to process the first time around we retry it later (if the error is retryable). In this case the timestamp - // will already be in the database but we don't want to treat the message as a duplicate. The isRetry flag is a simple workaround - // for this issue. - guard !Set(storage.getReceivedMessageTimestamps(using: transaction)).contains(envelope.timestamp) || isRetry else { throw Error.duplicateMessage } - storage.addReceivedMessageTimestamp(envelope.timestamp, using: transaction) // Decrypt the contents guard let ciphertext = envelope.content else { throw Error.noData } var plaintext: Data! @@ -159,6 +154,19 @@ public enum MessageReceiver { guard isValid else { throw Error.invalidMessage } + // If the message failed to process the first time around we retry it later (if the error is retryable). In this case the timestamp + // will already be in the database but we don't want to treat the message as a duplicate. The isRetry flag is a simple workaround + // for this issue. + if let message = message as? ClosedGroupControlMessage, case .new = message.kind { + // Allow duplicates in this case to avoid the following situation: + // • The app performed a background poll or received a push notification + // • This method was invoked and the received message timestamps table was updated + // • Processing wasn't finished + // • The user doesn't see the new closed group + } else { + guard !Set(storage.getReceivedMessageTimestamps(using: transaction)).contains(envelope.timestamp) || isRetry else { throw Error.duplicateMessage } + storage.addReceivedMessageTimestamp(envelope.timestamp, using: transaction) + } // Return return (message, proto) } else { From 6760341a2e7a56348828c2d1808088d75ca42b40 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 19 May 2021 08:49:20 +1000 Subject: [PATCH 03/10] Add missing retry --- Session/Utilities/BackgroundPoller.swift | 31 +++++++++++------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/Session/Utilities/BackgroundPoller.swift b/Session/Utilities/BackgroundPoller.swift index 4ce1f8147..3a79a7450 100644 --- a/Session/Utilities/BackgroundPoller.swift +++ b/Session/Utilities/BackgroundPoller.swift @@ -13,12 +13,6 @@ public final class BackgroundPoller : NSObject { promises = [] promises.append(pollForMessages()) promises.append(contentsOf: pollForClosedGroupMessages()) - let openGroups: [String:OpenGroup] = Storage.shared.getAllUserOpenGroups() - openGroups.values.forEach { openGroup in - let poller = OpenGroupPoller(for: openGroup) - poller.stop() - promises.append(poller.pollForNewMessages(isBackgroundPoll: true)) - } let v2OpenGroupServers = Set(Storage.shared.getAllV2OpenGroups().values.map { $0.server }) v2OpenGroupServers.forEach { server in let poller = OpenGroupPollerV2(for: server) @@ -27,7 +21,8 @@ public final class BackgroundPoller : NSObject { } when(resolved: promises).done { _ in completionHandler(.newData) - }.catch { _ in + }.catch { error in + SNLog("Background poll failed due to error: \(error)") completionHandler(.failed) } } @@ -45,17 +40,19 @@ public final class BackgroundPoller : NSObject { private static func getMessages(for publicKey: String) -> Promise { return SnodeAPI.getSwarm(for: publicKey).then(on: DispatchQueue.main) { swarm -> Promise in guard let snode = swarm.randomElement() else { throw SnodeAPI.Error.generic } - return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise in - let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey) - let promises = messages.compactMap { json -> Promise? in - // Use a best attempt approach here; we don't want to fail the entire process if one of the - // messages failed to parse. - guard let envelope = SNProtoEnvelope.from(json), - let data = try? envelope.serializedData() else { return nil } - let job = MessageReceiveJob(data: data, isBackgroundPoll: true) - return job.execute() + return attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.main) { + return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise in + let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey) + let promises = messages.compactMap { json -> Promise? in + // Use a best attempt approach here; we don't want to fail the entire process if one of the + // messages failed to parse. + guard let envelope = SNProtoEnvelope.from(json), + let data = try? envelope.serializedData() else { return nil } + let job = MessageReceiveJob(data: data, isBackgroundPoll: true) + return job.execute() + } + return when(fulfilled: promises) // The promise returned by MessageReceiveJob never rejects } - return when(fulfilled: promises) // The promise returned by MessageReceiveJob never rejects } } } From 8338ba3eca7fafca99715eeafd799ed6cc835e45 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 19 May 2021 13:32:42 +1000 Subject: [PATCH 04/10] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ Session/Home/HomeVC.swift | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 0a21b22a2..52eced0e1 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5138,7 +5138,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5207,7 +5207,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5268,7 +5268,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5338,7 +5338,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6223,7 +6223,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6291,7 +6291,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 246; + CURRENT_PROJECT_VERSION = 247; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 2808e224f..9fde3b929 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -231,10 +231,10 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv } } tableView.endUpdates() - // HACK: Moves can have conflicts with other 3 types of change. - // Just batch perform all the moves seperately to prevent crashing. - // Since all the changes are from original state to final state, - // it will still be correct if we pick the Moves out. + // HACK: Moves can have conflicts with the other 3 types of change. + // Just batch perform all the moves separately to prevent crashing. + // Since all the changes are from the original state to the final state, + // it will still be correct if we pick the moves out. tableView.beginUpdates() rowChanges.forEach { rowChange in let rowChange = rowChange as! YapDatabaseViewRowChange From 8dffa249bbd89a26b295906869088ed25073cd09 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 19 May 2021 13:43:24 +1000 Subject: [PATCH 05/10] Update version number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 52eced0e1..25ade3331 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5159,7 +5159,7 @@ INFOPLIST_FILE = SessionShareExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5233,7 +5233,7 @@ INFOPLIST_FILE = SessionShareExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5287,7 +5287,7 @@ INFOPLIST_FILE = SessionNotificationServiceExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -5362,7 +5362,7 @@ INFOPLIST_FILE = SessionNotificationServiceExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -6259,7 +6259,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; @@ -6327,7 +6327,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 1.11.0; + MARKETING_VERSION = 1.11.1; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_NAME = Session; From 4da8a0933c5db5b7d1cbe7192e8ccdd977624c2e Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 19 May 2021 15:15:54 +1000 Subject: [PATCH 06/10] Add file server instability modal --- Session.xcodeproj/project.pbxproj | 4 ++ Session/Home/HomeVC.swift | 8 ++++ Session/Sheets & Modals/FileServerModal.swift | 44 +++++++++++++++++++ .../General/SNUserDefaults.swift | 1 + 4 files changed, 57 insertions(+) create mode 100644 Session/Sheets & Modals/FileServerModal.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 25ade3331..322724eb6 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -773,6 +773,7 @@ C3DB66CC260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */; }; C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; }; C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */; }; + C3ECBBDB2654D4640081996B /* FileServerModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ECBBDA2654D4640081996B /* FileServerModal.swift */; }; C3ECBF7B257056B700EA7FCE /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ECBF7A257056B700EA7FCE /* Threading.swift */; }; C3F0A530255C80BC007BE2A3 /* NoopNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */; }; D2179CFC16BB0B3A0006F3AB /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */; }; @@ -1762,6 +1763,7 @@ C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditClosedGroupVC.swift; sourceTree = ""; }; C3E7134E251C867C009649BB /* Sodium+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Conversion.swift"; sourceTree = ""; }; + C3ECBBDA2654D4640081996B /* FileServerModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileServerModal.swift; sourceTree = ""; }; C3ECBF7A257056B700EA7FCE /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = ""; }; C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = ""; }; C3F0A5B2255C915C007BE2A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -2872,6 +2874,7 @@ B8A14D6F2589CE9000E70D57 /* KeyPairMigrationSuccessSheet.swift */, B86BD08323399ACF000F5AE3 /* Modal.swift */, C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */, + C3ECBBDA2654D4640081996B /* FileServerModal.swift */, ); path = "Sheets & Modals"; sourceTree = ""; @@ -4888,6 +4891,7 @@ 34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */, 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, 4CC613362227A00400E21A3A /* ConversationSearch.swift in Sources */, + C3ECBBDB2654D4640081996B /* FileServerModal.swift in Sources */, B82149B825D60393009C0F2A /* BlockedModal.swift in Sources */, B82B408C239A068800A248E7 /* RegisterVC.swift in Sources */, 346129991FD1E4DA00532771 /* SignalApp.m in Sources */, diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 9fde3b929..688aed4b7 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -164,6 +164,14 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) reload() + let userDefaults = UserDefaults.standard + if !userDefaults[.hasSeenFileServerInstabilityNotification] { + let fileServerModal = FileServerModal() + fileServerModal.modalPresentationStyle = .overFullScreen + fileServerModal.modalTransitionStyle = .crossDissolve + present(fileServerModal, animated: true, completion: nil) + userDefaults[.hasSeenFileServerInstabilityNotification] = true + } } deinit { diff --git a/Session/Sheets & Modals/FileServerModal.swift b/Session/Sheets & Modals/FileServerModal.swift new file mode 100644 index 000000000..d4a036fb3 --- /dev/null +++ b/Session/Sheets & Modals/FileServerModal.swift @@ -0,0 +1,44 @@ + +final class FileServerModal : Modal { + + override func populateContentView() { + // Title + let titleLabel = UILabel() + titleLabel.textColor = Colors.text + titleLabel.font = .boldSystemFont(ofSize: Values.largeFontSize) + titleLabel.text = "Session" + titleLabel.textAlignment = .center + // Message + let messageLabel = UILabel() + messageLabel.textColor = Colors.text + messageLabel.font = .systemFont(ofSize: Values.smallFontSize) + let message = "We're upgrading the way files are stored. File transfer may be unstable for the next 24-48 hours." + messageLabel.text = message + messageLabel.numberOfLines = 0 + messageLabel.lineBreakMode = .byWordWrapping + messageLabel.textAlignment = .center + // OK button + let okButton = UIButton() + okButton.set(.height, to: Values.mediumButtonHeight) + okButton.layer.cornerRadius = Modal.buttonCornerRadius + okButton.backgroundColor = Colors.buttonBackground + okButton.titleLabel!.font = .systemFont(ofSize: Values.smallFontSize) + okButton.setTitleColor(Colors.text, for: UIControl.State.normal) + okButton.setTitle("OK", for: UIControl.State.normal) + okButton.addTarget(self, action: #selector(close), for: UIControl.Event.touchUpInside) + // Button stack view + let buttonStackView = UIStackView(arrangedSubviews: [ okButton ]) + buttonStackView.axis = .horizontal + buttonStackView.spacing = Values.mediumSpacing + buttonStackView.distribution = .fillEqually + // Main stack view + let mainStackView = UIStackView(arrangedSubviews: [ titleLabel, messageLabel, buttonStackView ]) + mainStackView.axis = .vertical + mainStackView.spacing = Values.largeSpacing + contentView.addSubview(mainStackView) + mainStackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing) + mainStackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing) + contentView.pin(.trailing, to: .trailing, of: mainStackView, withInset: Values.largeSpacing) + contentView.pin(.bottom, to: .bottom, of: mainStackView, withInset: Values.largeSpacing) + } +} diff --git a/SessionUtilitiesKit/General/SNUserDefaults.swift b/SessionUtilitiesKit/General/SNUserDefaults.swift index aa563e94f..982fabe4f 100644 --- a/SessionUtilitiesKit/General/SNUserDefaults.swift +++ b/SessionUtilitiesKit/General/SNUserDefaults.swift @@ -8,6 +8,7 @@ public enum SNUserDefaults { case hasSeenLinkPreviewSuggestion case isUsingFullAPNs case isMigratingToV2KeyPair + case hasSeenFileServerInstabilityNotification } public enum Date : Swift.String { From 20e0103d2df3271e8c9368616054bf11f898bffd Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 20 May 2021 10:53:56 +1000 Subject: [PATCH 07/10] Switch to dedicated server --- .../File Server/FileServerAPIV2.swift | 22 +++++++++++-------- .../Jobs/AttachmentDownloadJob.swift | 5 +++-- SignalUtilitiesKit/To Do/OWSProfileManager.m | 5 +++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/SessionMessagingKit/File Server/FileServerAPIV2.swift b/SessionMessagingKit/File Server/FileServerAPIV2.swift index dd19b528c..16146b59a 100644 --- a/SessionMessagingKit/File Server/FileServerAPIV2.swift +++ b/SessionMessagingKit/File Server/FileServerAPIV2.swift @@ -5,8 +5,10 @@ import SessionSnodeKit public final class FileServerAPIV2 : NSObject { // MARK: Settings - @objc public static let server = "http://88.99.175.227" - public static let serverPublicKey = "7cb31905b55cd5580c686911debf672577b3fb0bff81df4ce2d5c4cb3a7aaa69" + @objc public static let oldServer = "http://88.99.175.227" + public static let oldServerPublicKey = "7cb31905b55cd5580c686911debf672577b3fb0bff81df4ce2d5c4cb3a7aaa69" + @objc public static let server = "http://filev2.getsession.org" + public static let serverPublicKey = "da21e1d886c6fbaea313f75298bd64aab03a97ce985b46bb2dad9f2089c8ee59" // MARK: Initialization private override init() { } @@ -47,7 +49,9 @@ public final class FileServerAPIV2 : NSObject { } // MARK: Convenience - private static func send(_ request: Request) -> Promise { + private static func send(_ request: Request, useOldServer: Bool) -> Promise { + let server = useOldServer ? oldServer : server + let serverPublicKey = useOldServer ? oldServerPublicKey : serverPublicKey let tsRequest: TSRequest switch request.verb { case .get: @@ -81,21 +85,21 @@ public final class FileServerAPIV2 : NSObject { let base64EncodedFile = file.base64EncodedString() let parameters = [ "file" : base64EncodedFile ] let request = Request(verb: .post, endpoint: "files", parameters: parameters) - return send(request).map(on: DispatchQueue.global(qos: .userInitiated)) { json in + return send(request, useOldServer: false).map(on: DispatchQueue.global(qos: .userInitiated)) { json in guard let fileID = json["result"] as? UInt64 else { throw Error.parsingFailed } return fileID } } - @objc(download:) - public static func objc_download(file: String) -> AnyPromise { + @objc(download:useOldServer:) + public static func objc_download(file: String, useOldServer: Bool) -> AnyPromise { guard let id = UInt64(file) else { return AnyPromise.from(Promise(error: Error.invalidURL)) } - return AnyPromise.from(download(id)) + return AnyPromise.from(download(id, useOldServer: useOldServer)) } - public static func download(_ file: UInt64) -> Promise { + public static func download(_ file: UInt64, useOldServer: Bool) -> Promise { let request = Request(verb: .get, endpoint: "files/\(file)") - return send(request).map(on: DispatchQueue.global(qos: .userInitiated)) { json in + return send(request, useOldServer: useOldServer).map(on: DispatchQueue.global(qos: .userInitiated)) { json in guard let base64EncodedFile = json["result"] as? String, let file = Data(base64Encoded: base64EncodedFile) else { throw Error.parsingFailed } return file } diff --git a/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift b/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift index d9b96b5b9..ef1897af7 100644 --- a/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift +++ b/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift @@ -100,11 +100,12 @@ public final class AttachmentDownloadJob : NSObject, Job, NSCoding { // NSObject }.catch(on: DispatchQueue.global()) { error in handleFailure(error) } - } else if pointer.downloadURL.contains(FileServerAPIV2.server) { + } else if pointer.downloadURL.contains(FileServerAPIV2.server) || pointer.downloadURL.contains(FileServerAPIV2.oldServer) { guard let fileAsString = pointer.downloadURL.split(separator: "/").last, let file = UInt64(fileAsString) else { return handleFailure(Error.invalidURL) } - FileServerAPIV2.download(file).done(on: DispatchQueue.global(qos: .userInitiated)) { data in + let useOldServer = pointer.downloadURL.contains(FileServerAPIV2.oldServer) + FileServerAPIV2.download(file, useOldServer: useOldServer).done(on: DispatchQueue.global(qos: .userInitiated)) { data in self.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure) }.catch(on: DispatchQueue.global()) { error in handleFailure(error) diff --git a/SignalUtilitiesKit/To Do/OWSProfileManager.m b/SignalUtilitiesKit/To Do/OWSProfileManager.m index c37b850f9..afc9428cc 100644 --- a/SignalUtilitiesKit/To Do/OWSProfileManager.m +++ b/SignalUtilitiesKit/To Do/OWSProfileManager.m @@ -806,9 +806,10 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); NSString *profilePictureURL = userProfile.avatarUrlPath; AnyPromise *promise; - if ([profilePictureURL containsString:SNFileServerAPIV2.server]) { + if ([profilePictureURL containsString:SNFileServerAPIV2.server] || [profilePictureURL containsString:SNFileServerAPIV2.oldServer]) { NSString *file = [profilePictureURL lastPathComponent]; - promise = [SNFileServerAPIV2 download:file]; + BOOL useOldServer = [profilePictureURL containsString:SNFileServerAPIV2.oldServer]; + promise = [SNFileServerAPIV2 download:file useOldServer:useOldServer]; } else { promise = [SNFileServerAPI downloadAttachmentFrom:profilePictureURL]; } From 08fc17e0f9c1203528fd89191d5d6be6cd7a9a7e Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 20 May 2021 12:03:59 +1000 Subject: [PATCH 08/10] Remove file server instability modal --- Session.xcodeproj/project.pbxproj | 4 -- Session/Home/HomeVC.swift | 8 ---- Session/Sheets & Modals/FileServerModal.swift | 44 ------------------- .../General/SNUserDefaults.swift | 1 - 4 files changed, 57 deletions(-) delete mode 100644 Session/Sheets & Modals/FileServerModal.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 322724eb6..25ade3331 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -773,7 +773,6 @@ C3DB66CC260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */; }; C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; }; C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */; }; - C3ECBBDB2654D4640081996B /* FileServerModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ECBBDA2654D4640081996B /* FileServerModal.swift */; }; C3ECBF7B257056B700EA7FCE /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ECBF7A257056B700EA7FCE /* Threading.swift */; }; C3F0A530255C80BC007BE2A3 /* NoopNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */; }; D2179CFC16BB0B3A0006F3AB /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */; }; @@ -1763,7 +1762,6 @@ C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditClosedGroupVC.swift; sourceTree = ""; }; C3E7134E251C867C009649BB /* Sodium+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Conversion.swift"; sourceTree = ""; }; - C3ECBBDA2654D4640081996B /* FileServerModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileServerModal.swift; sourceTree = ""; }; C3ECBF7A257056B700EA7FCE /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = ""; }; C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = ""; }; C3F0A5B2255C915C007BE2A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -2874,7 +2872,6 @@ B8A14D6F2589CE9000E70D57 /* KeyPairMigrationSuccessSheet.swift */, B86BD08323399ACF000F5AE3 /* Modal.swift */, C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */, - C3ECBBDA2654D4640081996B /* FileServerModal.swift */, ); path = "Sheets & Modals"; sourceTree = ""; @@ -4891,7 +4888,6 @@ 34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */, 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, 4CC613362227A00400E21A3A /* ConversationSearch.swift in Sources */, - C3ECBBDB2654D4640081996B /* FileServerModal.swift in Sources */, B82149B825D60393009C0F2A /* BlockedModal.swift in Sources */, B82B408C239A068800A248E7 /* RegisterVC.swift in Sources */, 346129991FD1E4DA00532771 /* SignalApp.m in Sources */, diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 688aed4b7..9fde3b929 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -164,14 +164,6 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) reload() - let userDefaults = UserDefaults.standard - if !userDefaults[.hasSeenFileServerInstabilityNotification] { - let fileServerModal = FileServerModal() - fileServerModal.modalPresentationStyle = .overFullScreen - fileServerModal.modalTransitionStyle = .crossDissolve - present(fileServerModal, animated: true, completion: nil) - userDefaults[.hasSeenFileServerInstabilityNotification] = true - } } deinit { diff --git a/Session/Sheets & Modals/FileServerModal.swift b/Session/Sheets & Modals/FileServerModal.swift deleted file mode 100644 index d4a036fb3..000000000 --- a/Session/Sheets & Modals/FileServerModal.swift +++ /dev/null @@ -1,44 +0,0 @@ - -final class FileServerModal : Modal { - - override func populateContentView() { - // Title - let titleLabel = UILabel() - titleLabel.textColor = Colors.text - titleLabel.font = .boldSystemFont(ofSize: Values.largeFontSize) - titleLabel.text = "Session" - titleLabel.textAlignment = .center - // Message - let messageLabel = UILabel() - messageLabel.textColor = Colors.text - messageLabel.font = .systemFont(ofSize: Values.smallFontSize) - let message = "We're upgrading the way files are stored. File transfer may be unstable for the next 24-48 hours." - messageLabel.text = message - messageLabel.numberOfLines = 0 - messageLabel.lineBreakMode = .byWordWrapping - messageLabel.textAlignment = .center - // OK button - let okButton = UIButton() - okButton.set(.height, to: Values.mediumButtonHeight) - okButton.layer.cornerRadius = Modal.buttonCornerRadius - okButton.backgroundColor = Colors.buttonBackground - okButton.titleLabel!.font = .systemFont(ofSize: Values.smallFontSize) - okButton.setTitleColor(Colors.text, for: UIControl.State.normal) - okButton.setTitle("OK", for: UIControl.State.normal) - okButton.addTarget(self, action: #selector(close), for: UIControl.Event.touchUpInside) - // Button stack view - let buttonStackView = UIStackView(arrangedSubviews: [ okButton ]) - buttonStackView.axis = .horizontal - buttonStackView.spacing = Values.mediumSpacing - buttonStackView.distribution = .fillEqually - // Main stack view - let mainStackView = UIStackView(arrangedSubviews: [ titleLabel, messageLabel, buttonStackView ]) - mainStackView.axis = .vertical - mainStackView.spacing = Values.largeSpacing - contentView.addSubview(mainStackView) - mainStackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing) - mainStackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing) - contentView.pin(.trailing, to: .trailing, of: mainStackView, withInset: Values.largeSpacing) - contentView.pin(.bottom, to: .bottom, of: mainStackView, withInset: Values.largeSpacing) - } -} diff --git a/SessionUtilitiesKit/General/SNUserDefaults.swift b/SessionUtilitiesKit/General/SNUserDefaults.swift index 982fabe4f..aa563e94f 100644 --- a/SessionUtilitiesKit/General/SNUserDefaults.swift +++ b/SessionUtilitiesKit/General/SNUserDefaults.swift @@ -8,7 +8,6 @@ public enum SNUserDefaults { case hasSeenLinkPreviewSuggestion case isUsingFullAPNs case isMigratingToV2KeyPair - case hasSeenFileServerInstabilityNotification } public enum Date : Swift.String { From c84a94247892a416c42bfe708118565bf057f4d1 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 20 May 2021 13:57:42 +1000 Subject: [PATCH 09/10] Fix push notification handling This was crashing every time the extension started --- SessionMessagingKit/Database/OWSPrimaryStorage.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/SessionMessagingKit/Database/OWSPrimaryStorage.m b/SessionMessagingKit/Database/OWSPrimaryStorage.m index d35635cae..ae897bf48 100644 --- a/SessionMessagingKit/Database/OWSPrimaryStorage.m +++ b/SessionMessagingKit/Database/OWSPrimaryStorage.m @@ -69,9 +69,6 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage) _dbReadPool = [[YapDatabaseConnectionPool alloc] initWithDatabase:self.database]; _dbReadWriteConnection = [self newDatabaseConnection]; _uiDatabaseConnection = [self newDatabaseConnection]; - - // Vacuum the database - [self.dbReadWriteConnection vacuum]; // Increase object cache limit. Default is 250. _uiDatabaseConnection.objectCacheLimit = 500; From fe3493ff127431a2e77418c7571754e4d0aa58f4 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 20 May 2021 13:58:31 +1000 Subject: [PATCH 10/10] Update version number --- Session.xcodeproj/project.pbxproj | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 25ade3331..878709073 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5138,7 +5138,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5159,7 +5159,7 @@ INFOPLIST_FILE = SessionShareExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5207,7 +5207,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5233,7 +5233,7 @@ INFOPLIST_FILE = SessionShareExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5268,7 +5268,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5287,7 +5287,7 @@ INFOPLIST_FILE = SessionNotificationServiceExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -5338,7 +5338,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5362,7 +5362,7 @@ INFOPLIST_FILE = SessionNotificationServiceExtension/Meta/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -6223,7 +6223,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6259,7 +6259,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; @@ -6291,7 +6291,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 249; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6327,7 +6327,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 1.11.1; + MARKETING_VERSION = 1.11.2; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_NAME = Session;