Merge pull request #629 from RyanRory/bug-fixes-on-1.12.8
Bug fixes on 1.12.8
This commit is contained in:
commit
51e989e58b
|
@ -140,6 +140,7 @@
|
|||
7B251C3627D82D9E001A6284 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; };
|
||||
7B4C75CB26B37E0F0000AC89 /* UnsendRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */; };
|
||||
7B4C75CD26BB92060000AC89 /* DeletedMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C75CC26BB92060000AC89 /* DeletedMessageView.swift */; };
|
||||
7B703747283CA919000DCF35 /* Storage+Calls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B703746283CA919000DCF35 /* Storage+Calls.swift */; };
|
||||
7B7CB189270430D20079FF93 /* CallMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB188270430D20079FF93 /* CallMessageView.swift */; };
|
||||
7B7CB18B270591630079FF93 /* ShareLogsModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB18A270591630079FF93 /* ShareLogsModal.swift */; };
|
||||
7B7CB18E270D066F0079FF93 /* IncomingCallBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7CB18D270D066F0079FF93 /* IncomingCallBanner.swift */; };
|
||||
|
@ -1129,6 +1130,7 @@
|
|||
7B2DB2AD26F1B0FF0035B509 /* si */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = si; path = si.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsendRequest.swift; sourceTree = "<group>"; };
|
||||
7B4C75CC26BB92060000AC89 /* DeletedMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedMessageView.swift; sourceTree = "<group>"; };
|
||||
7B703746283CA919000DCF35 /* Storage+Calls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Calls.swift"; sourceTree = "<group>"; };
|
||||
7B7CB188270430D20079FF93 /* CallMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallMessageView.swift; sourceTree = "<group>"; };
|
||||
7B7CB18A270591630079FF93 /* ShareLogsModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareLogsModal.swift; sourceTree = "<group>"; };
|
||||
7B7CB18D270D066F0079FF93 /* IncomingCallBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingCallBanner.swift; sourceTree = "<group>"; };
|
||||
|
@ -2754,6 +2756,7 @@
|
|||
B8D8F19225661BF80092EF10 /* Storage+Messaging.swift */,
|
||||
B8D8F18825661BA50092EF10 /* Storage+OpenGroups.swift */,
|
||||
C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */,
|
||||
7B703746283CA919000DCF35 /* Storage+Calls.swift */,
|
||||
C33FDA69255A57F900E217F9 /* SSKPreferences.swift */,
|
||||
C33FDB25255A580900E217F9 /* TSDatabaseSecondaryIndexes.h */,
|
||||
C33FDB20255A580900E217F9 /* TSDatabaseSecondaryIndexes.m */,
|
||||
|
@ -4701,6 +4704,7 @@
|
|||
C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */,
|
||||
C3A3A156256E1B91004D228D /* ProtoUtils.m in Sources */,
|
||||
C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */,
|
||||
7B703747283CA919000DCF35 /* Storage+Calls.swift in Sources */,
|
||||
C352A32F2557549C00338F3E /* NotifyPNServerJob.swift in Sources */,
|
||||
7B4C75CB26B37E0F0000AC89 /* UnsendRequest.swift in Sources */,
|
||||
C300A5F22554B09800555489 /* MessageSender.swift in Sources */,
|
||||
|
|
|
@ -32,6 +32,8 @@ public class ConversationSearchController : NSObject {
|
|||
|
||||
@objc
|
||||
public let resultsBar: SearchResultsBar = SearchResultsBar()
|
||||
|
||||
private var lastSearchText: String?
|
||||
|
||||
// MARK: Initializer
|
||||
|
||||
|
@ -88,8 +90,10 @@ extension ConversationSearchController : UISearchResultsUpdating {
|
|||
return
|
||||
}
|
||||
let searchText = FullTextSearchFinder.normalize(text: rawSearchText)
|
||||
lastSearchText = searchText
|
||||
|
||||
guard searchText.count >= ConversationSearchController.kMinimumSearchTextLength else {
|
||||
lastSearchText = nil
|
||||
self.resultsBar.updateResults(resultSet: nil)
|
||||
self.delegate?.conversationSearchController(self, didUpdateSearchResults: nil)
|
||||
return
|
||||
|
@ -102,7 +106,7 @@ extension ConversationSearchController : UISearchResultsUpdating {
|
|||
}
|
||||
resultSet = self.dbSearcher.searchWithinConversation(thread: self.thread, searchText: searchText, transaction: transaction)
|
||||
}, completionBlock: { [weak self] in
|
||||
guard let self = self else {
|
||||
guard let self = self, searchText == self.lastSearchText else {
|
||||
return
|
||||
}
|
||||
self.resultsBar.updateResults(resultSet: resultSet)
|
||||
|
@ -121,7 +125,6 @@ extension ConversationSearchController : SearchResultsBarDelegate {
|
|||
return
|
||||
}
|
||||
|
||||
BenchEventStart(title: "Conversation Search Nav", eventId: "Conversation Search Nav: \(searchResult.messageId)")
|
||||
self.delegate?.conversationSearchController(self, didSelectMessageId: searchResult.messageId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,12 +429,12 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
Storage.write { transaction in
|
||||
self.thread.setDraft(text, transaction: transaction)
|
||||
}
|
||||
self.resignFirstResponder()
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
mediaCache.removeAllObjects()
|
||||
self.resignFirstResponder()
|
||||
}
|
||||
|
||||
override func appDidBecomeActive(_ notification: Notification) {
|
||||
|
@ -922,7 +922,10 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
}
|
||||
|
||||
func conversationSearchController(_ conversationSearchController: ConversationSearchController, didSelectMessageId interactionID: String) {
|
||||
scrollToInteraction(with: interactionID)
|
||||
scrollToInteraction(with: interactionID, highlighted: true)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
|
||||
self.highlightFocusedMessageIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
func scrollToInteraction(with interactionID: String, position: UITableView.ScrollPosition = .middle, isAnimated: Bool = true, highlighted: Bool = false) {
|
||||
|
|
|
@ -333,13 +333,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
selector:@selector(applicationWillEnterForeground:)
|
||||
name:OWSApplicationWillEnterForegroundNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[self addNotificationListeners];
|
||||
|
||||
[self touchDbAsync];
|
||||
}
|
||||
|
||||
- (void)touchDbAsync
|
||||
|
|
|
@ -146,7 +146,7 @@ final class LinkPreviewView : UIView {
|
|||
// Body text view
|
||||
bodyTextViewContainer.subviews.forEach { $0.removeFromSuperview() }
|
||||
if let viewItem = viewItem {
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: sentLinkPreviewTextColor, searchText: delegate.lastSearchedText, delegate: delegate)
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: sentLinkPreviewTextColor, delegate: delegate)
|
||||
self.bodyTextView = bodyTextView
|
||||
bodyTextViewContainer.addSubview(bodyTextView)
|
||||
bodyTextView.pin(to: bodyTextViewContainer, withInset: 12)
|
||||
|
|
|
@ -351,7 +351,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
|||
stackView.addArrangedSubview(quoteViewContainer)
|
||||
}
|
||||
// Body text view
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, searchText: delegate?.lastSearchedText, delegate: self)
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, delegate: self)
|
||||
self.bodyTextView = bodyTextView
|
||||
stackView.addArrangedSubview(bodyTextView)
|
||||
// Constraints
|
||||
|
@ -383,7 +383,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
|||
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0 {
|
||||
let inset: CGFloat = 12
|
||||
let maxWidth = size.width - 2 * inset
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, searchText: delegate?.lastSearchedText, delegate: self)
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, delegate: self)
|
||||
self.bodyTextView = bodyTextView
|
||||
stackView.addArrangedSubview(UIView(wrapping: bodyTextView, withInsets: UIEdgeInsets(top: 0, left: inset, bottom: inset, right: inset)))
|
||||
}
|
||||
|
@ -420,9 +420,8 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
|||
let documentView = DocumentView(viewItem: viewItem, textColor: bodyLabelTextColor)
|
||||
stackView.addArrangedSubview(documentView)
|
||||
// Body text view
|
||||
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0,
|
||||
let delegate = delegate { // delegate should always be set at this point
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, searchText: delegate.lastSearchedText, delegate: self)
|
||||
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0 {
|
||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, delegate: self)
|
||||
self.bodyTextView = bodyTextView
|
||||
stackView.addArrangedSubview(bodyTextView)
|
||||
}
|
||||
|
@ -704,7 +703,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
|||
return isGroupThread && viewItem.shouldShowSenderProfilePicture && senderSessionID != nil
|
||||
}
|
||||
|
||||
static func getBodyTextView(for viewItem: ConversationViewItem, with availableWidth: CGFloat, textColor: UIColor, searchText: String?, delegate: UITextViewDelegate & BodyTextViewDelegate) -> UITextView {
|
||||
static func getBodyTextView(for viewItem: ConversationViewItem, with availableWidth: CGFloat, textColor: UIColor, delegate: UITextViewDelegate & BodyTextViewDelegate) -> UITextView {
|
||||
// Take care of:
|
||||
// • Highlighting mentions
|
||||
// • Linkification
|
||||
|
@ -718,20 +717,6 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
|||
.font : UIFont.systemFont(ofSize: getFontSize(for: viewItem))
|
||||
]
|
||||
let attributedText = NSMutableAttributedString(attributedString: MentionUtilities.highlightMentions(in: message.body ?? "", isOutgoingMessage: isOutgoing, threadID: viewItem.interaction.uniqueThreadId, attributes: attributes))
|
||||
if let searchText = searchText, searchText.count >= ConversationSearchController.kMinimumSearchTextLength {
|
||||
let normalizedSearchText = FullTextSearchFinder.normalize(text: searchText)
|
||||
do {
|
||||
let regex = try NSRegularExpression(pattern: NSRegularExpression.escapedPattern(for: normalizedSearchText), options: .caseInsensitive)
|
||||
let matches = regex.matches(in: attributedText.string, options: .withoutAnchoringBounds, range: NSRange(location: 0, length: (attributedText.string as NSString).length))
|
||||
for match in matches {
|
||||
guard match.range.location + match.range.length < attributedText.length else { continue }
|
||||
attributedText.addAttribute(.backgroundColor, value: UIColor.white, range: match.range)
|
||||
attributedText.addAttribute(.foregroundColor, value: UIColor.black, range: match.range)
|
||||
}
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
result.attributedText = attributedText
|
||||
result.dataDetectorTypes = .link
|
||||
result.backgroundColor = .clear
|
||||
|
|
|
@ -92,6 +92,19 @@ class ImagePickerGridController: UICollectionViewController, PhotoLibraryDelegat
|
|||
selectionPanGesture.delegate = self
|
||||
self.selectionPanGesture = selectionPanGesture
|
||||
collectionView.addGestureRecognizer(selectionPanGesture)
|
||||
|
||||
if #available(iOS 14, *) {
|
||||
if PHPhotoLibrary.authorizationStatus(for: .readWrite) == .limited {
|
||||
let addSeletedPhotoButton = UIBarButtonItem.init(barButtonSystemItem: .add, target: self, action: #selector(addSelectedPhoto))
|
||||
self.navigationItem.rightBarButtonItem = addSeletedPhotoButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func addSelectedPhoto(_ sender: Any) {
|
||||
if #available(iOS 14, *) {
|
||||
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self)
|
||||
}
|
||||
}
|
||||
|
||||
var selectionPanGesture: UIPanGestureRecognizer?
|
||||
|
|
|
@ -56,10 +56,15 @@ extension AppDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
private func insertCallInfoMessage(for message: CallMessage, using transaction: YapDatabaseReadWriteTransaction) -> TSInfoMessage {
|
||||
private func insertCallInfoMessage(for message: CallMessage, using transaction: YapDatabaseReadWriteTransaction) -> TSInfoMessage? {
|
||||
guard let sender = message.sender, let uuid = message.uuid else { return nil }
|
||||
var receivedCalls = Storage.shared.getReceivedCalls(for: sender, using: transaction)
|
||||
guard !receivedCalls.contains(uuid) else { return nil }
|
||||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
|
||||
let infoMessage = TSInfoMessage.from(message, associatedWith: thread)
|
||||
infoMessage.save(with: transaction)
|
||||
receivedCalls.insert(message.uuid!)
|
||||
Storage.shared.setReceivedCalls(to: receivedCalls, for: sender, using: transaction)
|
||||
return infoMessage
|
||||
}
|
||||
|
||||
|
@ -78,20 +83,22 @@ extension AppDelegate {
|
|||
guard CurrentAppContext().isMainApp else { return }
|
||||
guard let timestamp = message.sentTimestamp, TimestampUtils.isWithinOneMinute(timestamp: timestamp) else {
|
||||
// Add missed call message for call offer messages from more than one minute
|
||||
let infoMessage = self.insertCallInfoMessage(for: message, using: transaction)
|
||||
infoMessage.updateCallInfoMessage(.missed, using: transaction)
|
||||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
|
||||
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
|
||||
if let infoMessage = self.insertCallInfoMessage(for: message, using: transaction) {
|
||||
infoMessage.updateCallInfoMessage(.missed, using: transaction)
|
||||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
|
||||
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
|
||||
}
|
||||
return
|
||||
}
|
||||
guard SSKPreferences.areCallsEnabled else {
|
||||
let infoMessage = self.insertCallInfoMessage(for: message, using: transaction)
|
||||
infoMessage.updateCallInfoMessage(.permissionDenied, using: transaction)
|
||||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
|
||||
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
|
||||
let contactName = Storage.shared.getContact(with: message.sender!, using: transaction)?.displayName(for: Contact.Context.regular) ?? message.sender!
|
||||
DispatchQueue.main.async {
|
||||
self.showMissedCallTipsIfNeeded(caller: contactName)
|
||||
if let infoMessage = self.insertCallInfoMessage(for: message, using: transaction) {
|
||||
infoMessage.updateCallInfoMessage(.permissionDenied, using: transaction)
|
||||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
|
||||
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
|
||||
let contactName = Storage.shared.getContact(with: message.sender!, using: transaction)?.displayName(for: Contact.Context.regular) ?? message.sender!
|
||||
DispatchQueue.main.async {
|
||||
self.showMissedCallTipsIfNeeded(caller: contactName)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -106,7 +113,7 @@ extension AppDelegate {
|
|||
// Handle UI
|
||||
if let caller = message.sender, let uuid = message.uuid {
|
||||
let call = SessionCall(for: caller, uuid: uuid, mode: .answer)
|
||||
call.callMessageID = infoMessage.uniqueId
|
||||
call.callMessageID = infoMessage?.uniqueId
|
||||
self.showCallUIForCall(call)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,16 +42,19 @@ public final class BackgroundPoller : NSObject {
|
|||
return attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.main) {
|
||||
SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise<Void> in
|
||||
let (messages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey)
|
||||
var processedMessages: [JSON] = []
|
||||
let promises = messages.compactMap { json -> Promise<Void>? 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, serverHash: json["hash"] as? String, isBackgroundPoll: true)
|
||||
processedMessages.append(json)
|
||||
return job.execute()
|
||||
}
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value & `receivedMessageHashes`
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, namespace: SnodeAPI.defaultNamespace, associatedWith: publicKey, from: lastRawMessage)
|
||||
SnodeAPI.updateReceivedMessages(from: processedMessages, associatedWith: publicKey)
|
||||
|
||||
return when(fulfilled: promises) // The promise returned by MessageReceiveJob never rejects
|
||||
}
|
||||
|
@ -82,16 +85,19 @@ public final class BackgroundPoller : NSObject {
|
|||
for result in results {
|
||||
if case .fulfilled(let rawResponse) = result {
|
||||
let (messages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey)
|
||||
var processedMessages: [JSON] = []
|
||||
let jobPromises = messages.compactMap { json -> Promise<Void>? 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, serverHash: json["hash"] as? String, isBackgroundPoll: true)
|
||||
processedMessages.append(json)
|
||||
return job.execute()
|
||||
}
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value & `receivedMessageHashes`
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, namespace: namespaces[index], associatedWith: publicKey, from: lastRawMessage)
|
||||
SnodeAPI.updateReceivedMessages(from: processedMessages, associatedWith: publicKey)
|
||||
promises += jobPromises
|
||||
}
|
||||
index += 1
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
extension Storage {
|
||||
|
||||
private static let receivedCallsCollection = "LokiReceivedCallsCollection"
|
||||
|
||||
public func getReceivedCalls(for publicKey: String, using transaction: Any) -> Set<String> {
|
||||
var result: Set<String>?
|
||||
guard let transaction = transaction as? YapDatabaseReadTransaction else { return [] }
|
||||
result = transaction.object(forKey: publicKey, inCollection: Storage.receivedCallsCollection) as? Set<String>
|
||||
return result ?? []
|
||||
}
|
||||
|
||||
public func setReceivedCalls(to receivedCalls: Set<String>, for publicKey: String, using transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(receivedCalls, forKey: publicKey, inCollection: Storage.receivedCallsCollection)
|
||||
}
|
||||
}
|
|
@ -122,6 +122,7 @@ public final class ClosedGroupPoller : NSObject {
|
|||
if !rawMessages.isEmpty {
|
||||
SNLog("Received \(rawMessages.count) new message(s) in closed group with public key: \(groupPublicKey).")
|
||||
}
|
||||
var processedMessages: [JSON] = []
|
||||
rawMessages.forEach { json in
|
||||
guard let envelope = SNProtoEnvelope.from(json) else { return }
|
||||
do {
|
||||
|
@ -130,13 +131,15 @@ public final class ClosedGroupPoller : NSObject {
|
|||
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||
SessionMessagingKit.JobQueue.shared.add(job, using: transaction)
|
||||
}
|
||||
processedMessages.append(json)
|
||||
} catch {
|
||||
SNLog("Failed to deserialize envelope due to error: \(error).")
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value & `receivedMessageHashes`
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, namespace: SnodeAPI.closedGroupNamespace, associatedWith: groupPublicKey, from: lastRawMessage)
|
||||
SnodeAPI.updateReceivedMessages(from: processedMessages, associatedWith: groupPublicKey)
|
||||
}
|
||||
promise.catch2 { error in
|
||||
SNLog("Polling failed for closed group with public key: \(groupPublicKey) due to error: \(error).")
|
||||
|
|
|
@ -98,6 +98,7 @@ public final class Poller : NSObject {
|
|||
if !messages.isEmpty {
|
||||
SNLog("Received \(messages.count) new message(s).")
|
||||
}
|
||||
var processedMessages: [JSON] = []
|
||||
messages.forEach { json in
|
||||
guard let envelope = SNProtoEnvelope.from(json) else { return }
|
||||
do {
|
||||
|
@ -106,13 +107,15 @@ public final class Poller : NSObject {
|
|||
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||
SessionMessagingKit.JobQueue.shared.add(job, using: transaction)
|
||||
}
|
||||
processedMessages.append(json)
|
||||
} catch {
|
||||
SNLog("Failed to deserialize envelope due to error: \(error).")
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value & `receivedMessageHashes`
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, namespace: SnodeAPI.defaultNamespace, associatedWith: userPublicKey, from: lastRawMessage)
|
||||
SnodeAPI.updateReceivedMessages(from: processedMessages, associatedWith: userPublicKey)
|
||||
|
||||
strongSelf.pollCount += 1
|
||||
if strongSelf.pollCount == Poller.maxPollCount {
|
||||
|
|
|
@ -96,6 +96,11 @@ public protocol SessionMessagingKitStorageProtocol {
|
|||
func setAttachmentState(to state: TSAttachmentPointerState, for pointer: TSAttachmentPointer, associatedWith tsIncomingMessageID: String, using transaction: Any)
|
||||
/// Also touches the associated message.
|
||||
func persist(_ stream: TSAttachmentStream, associatedWith tsIncomingMessageID: String, using transaction: Any)
|
||||
|
||||
// MARK: - Calls
|
||||
|
||||
func getReceivedCalls(for publicKey: String, using transaction: Any) -> Set<String>
|
||||
func setReceivedCalls(to receivedCalls: Set<String>, for publicKey: String, using transaction: Any)
|
||||
}
|
||||
|
||||
extension Storage: SessionMessagingKitStorageProtocol, SessionSnodeKitStorageProtocol {}
|
||||
|
|
|
@ -705,6 +705,20 @@ public final class SnodeAPI : NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
public static func updateReceivedMessages(from messages: [JSON], associatedWith publicKey: String) {
|
||||
let oldReceivedMessages = SNSnodeKitConfiguration.shared.storage.getReceivedMessages(for: publicKey)
|
||||
var newReceivedMessages = oldReceivedMessages
|
||||
for message in messages {
|
||||
guard let hash = message["hash"] as? String else { continue }
|
||||
newReceivedMessages.insert(hash)
|
||||
}
|
||||
if oldReceivedMessages != newReceivedMessages {
|
||||
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
|
||||
SNSnodeKitConfiguration.shared.storage.setReceivedMessages(to: newReceivedMessages, for: publicKey, using: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func removeDuplicates(from rawMessages: [JSON], associatedWith publicKey: String) -> [JSON] {
|
||||
let oldReceivedMessages = SNSnodeKitConfiguration.shared.storage.getReceivedMessages(for: publicKey)
|
||||
var newReceivedMessages = oldReceivedMessages
|
||||
|
@ -717,12 +731,6 @@ public final class SnodeAPI : NSObject {
|
|||
newReceivedMessages.insert(hash)
|
||||
return !isDuplicate
|
||||
}
|
||||
// Avoid the sync write transaction if possible
|
||||
if oldReceivedMessages != newReceivedMessages {
|
||||
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
|
||||
SNSnodeKitConfiguration.shared.storage.setReceivedMessages(to: newReceivedMessages, for: publicKey, using: transaction)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -752,6 +760,9 @@ public final class SnodeAPI : NSObject {
|
|||
case 500, 502, 503:
|
||||
// The snode is unreachable
|
||||
handleBadSnode()
|
||||
case 404:
|
||||
// May caused by invalid open groups
|
||||
SNLog("Can't reach the server.")
|
||||
case 406:
|
||||
SNLog("The user's clock is out of sync with the service node network.")
|
||||
return Error.clockOutOfSync
|
||||
|
|
|
@ -110,7 +110,6 @@ extension Storage {
|
|||
if now >= expirationDate {
|
||||
Storage.writeSync { transaction in
|
||||
self.removeLastMessageHashInfo(for: snode, namespace: namespace, associatedWith: publicKey, using: transaction)
|
||||
self.setReceivedMessages(to: Set(), for: publicKey, using: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue