Merge pull request #594 from RyanRory/bug-fixes-1.11.23

Bug fixes for 1.11.22
This commit is contained in:
RyanZhao 2022-03-21 14:11:42 +11:00 committed by GitHub
commit 9e020948d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 41 additions and 114 deletions

View File

@ -196,7 +196,6 @@
B8566C6C256F60F50045A0B9 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2D1255B6DAF007E1867 /* OWSUserProfile.m */; }; B8566C6C256F60F50045A0B9 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2D1255B6DAF007E1867 /* OWSUserProfile.m */; };
B8566C7D256F62030045A0B9 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2D3255B6DAF007E1867 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; }; B8566C7D256F62030045A0B9 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2D3255B6DAF007E1867 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
B8569AC325CB5D2900DBA3DB /* ConversationVC+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */; }; B8569AC325CB5D2900DBA3DB /* ConversationVC+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */; };
B8569AD325CBA13D00DBA3DB /* MediaTextOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */; };
B8569AE325CBB19A00DBA3DB /* DocumentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AE225CBB19A00DBA3DB /* DocumentView.swift */; }; B8569AE325CBB19A00DBA3DB /* DocumentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AE225CBB19A00DBA3DB /* DocumentView.swift */; };
B866CE112581C1A900535CC4 /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; }; B866CE112581C1A900535CC4 /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; };
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; }; B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
@ -1224,7 +1223,6 @@
B8544E3223D50E4900299F14 /* SNAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SNAppearance.swift; sourceTree = "<group>"; }; B8544E3223D50E4900299F14 /* SNAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SNAppearance.swift; sourceTree = "<group>"; };
B8566C62256F55930045A0B9 /* OWSLinkPreview+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OWSLinkPreview+Conversion.swift"; sourceTree = "<group>"; }; B8566C62256F55930045A0B9 /* OWSLinkPreview+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OWSLinkPreview+Conversion.swift"; sourceTree = "<group>"; };
B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConversationVC+Interaction.swift"; sourceTree = "<group>"; }; B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConversationVC+Interaction.swift"; sourceTree = "<group>"; };
B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaTextOverlayView.swift; sourceTree = "<group>"; };
B8569AE225CBB19A00DBA3DB /* DocumentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentView.swift; sourceTree = "<group>"; }; B8569AE225CBB19A00DBA3DB /* DocumentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentView.swift; sourceTree = "<group>"; };
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; }; B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; }; B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; };
@ -2171,7 +2169,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
34A8B3502190A40E00218A25 /* MediaAlbumView.swift */, 34A8B3502190A40E00218A25 /* MediaAlbumView.swift */,
B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */,
3488F9352191CC4000E524CC /* MediaView.swift */, 3488F9352191CC4000E524CC /* MediaView.swift */,
B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */, B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */,
B8F5F71925F1B35C003BF8D4 /* MediaPlaceholderView.swift */, B8F5F71925F1B35C003BF8D4 /* MediaPlaceholderView.swift */,
@ -4941,7 +4938,6 @@
341341EF2187467A00192D59 /* ConversationViewModel.m in Sources */, 341341EF2187467A00192D59 /* ConversationViewModel.m in Sources */,
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */, 4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */, C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */,
B8569AD325CBA13D00DBA3DB /* MediaTextOverlayView.swift in Sources */,
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */, 4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */, B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */,
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */, 34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,

View File

@ -544,14 +544,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
} else { } else {
guard let albumView = cell.albumView else { return } guard let albumView = cell.albumView else { return }
let locationInCell = gestureRecognizer.location(in: cell) let locationInCell = gestureRecognizer.location(in: cell)
// Figure out whether the "read more" button was tapped // Figure out which of the media views was tapped
if let overlayView = cell.mediaTextOverlayView {
let locationInOverlayView = cell.convert(locationInCell, to: overlayView)
if let readMoreButton = overlayView.readMoreButton, readMoreButton.frame.contains(locationInOverlayView) {
return showFullText(viewItem) // HACK: This is a dirty way to do this
}
}
// Otherwise, figure out which of the media views was tapped
let locationInAlbumView = cell.convert(locationInCell, to: albumView) let locationInAlbumView = cell.convert(locationInCell, to: albumView)
guard let mediaView = albumView.mediaView(forLocation: locationInAlbumView) else { return } guard let mediaView = albumView.mediaView(forLocation: locationInAlbumView) else { return }
if albumView.isMoreItemsView(mediaView: mediaView) && viewItem.mediaAlbumHasFailedAttachment() { if albumView.isMoreItemsView(mediaView: mediaView) && viewItem.mediaAlbumHasFailedAttachment() {
@ -590,10 +583,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
navigationController!.present(shareVC, animated: true, completion: nil) navigationController!.present(shareVC, animated: true, completion: nil)
} }
case .textOnlyMessage: case .textOnlyMessage:
if let preview = viewItem.linkPreview, let urlAsString = preview.urlString, let url = URL(string: urlAsString) { if let reply = viewItem.quotedReply {
// Open the link preview URL
openURL(url)
} else if let reply = viewItem.quotedReply {
// Scroll to the source of the reply // Scroll to the source of the reply
guard let indexPath = viewModel.ensureLoadWindowContainsQuotedReply(reply) else { return } guard let indexPath = viewModel.ensureLoadWindowContainsQuotedReply(reply) else { return }
messagesTableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.middle, animated: true) messagesTableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.middle, animated: true)

View File

@ -12,6 +12,7 @@ final class LinkPreviewView : UIView {
let isOutgoing = (viewItem!.interaction.interactionType() == .outgoingMessage) let isOutgoing = (viewItem!.interaction.interactionType() == .outgoingMessage)
switch (isOutgoing, AppModeManager.shared.currentAppMode) { switch (isOutgoing, AppModeManager.shared.currentAppMode) {
case (true, .dark), (false, .light): return .black case (true, .dark), (false, .light): return .black
case (true, .light): return Colors.grey
default: return .white default: return .white
} }
}() }()
@ -57,6 +58,8 @@ final class LinkPreviewView : UIView {
result.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside) result.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
return result return result
}() }()
var bodyTextView: UITextView?
// MARK: Settings // MARK: Settings
private static let loaderSize: CGFloat = 24 private static let loaderSize: CGFloat = 24
@ -133,15 +136,7 @@ final class LinkPreviewView : UIView {
loader.alpha = (image != nil) ? 0 : 1 loader.alpha = (image != nil) ? 0 : 1
if image != nil { loader.stopAnimating() } else { loader.startAnimating() } if image != nil { loader.stopAnimating() } else { loader.startAnimating() }
// Title // Title
let isSent = (linkPreviewState is LinkPreviewSent) titleLabel.textColor = sentLinkPreviewTextColor
let isOutgoing = (viewItem?.interaction.interactionType() == .outgoingMessage)
let textColor: UIColor
if isSent && isOutgoing && isLightMode {
textColor = .white
} else {
textColor = isDarkMode ? .white : .black
}
titleLabel.textColor = textColor
titleLabel.text = linkPreviewState.title() titleLabel.text = linkPreviewState.title()
// Horizontal stack view // Horizontal stack view
switch linkPreviewState { switch linkPreviewState {
@ -152,6 +147,7 @@ final class LinkPreviewView : UIView {
bodyTextViewContainer.subviews.forEach { $0.removeFromSuperview() } bodyTextViewContainer.subviews.forEach { $0.removeFromSuperview() }
if let viewItem = viewItem { 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, searchText: delegate.lastSearchedText, delegate: delegate)
self.bodyTextView = bodyTextView
bodyTextViewContainer.addSubview(bodyTextView) bodyTextViewContainer.addSubview(bodyTextView)
bodyTextView.pin(to: bodyTextViewContainer, withInset: 12) bodyTextView.pin(to: bodyTextViewContainer, withInset: 12)
} }

View File

@ -1,74 +0,0 @@
import UIKit
/// Shown over a media message if it has a message body.
final class MediaTextOverlayView : UIView {
private let viewItem: ConversationViewItem
private let albumViewWidth: CGFloat
private let delegate: MessageCellDelegate
private let textColor: UIColor
var readMoreButton: UIButton?
// MARK: Settings
private static let maxHeight: CGFloat = 88;
// MARK: Lifecycle
init(viewItem: ConversationViewItem, albumViewWidth: CGFloat, textColor: UIColor, delegate: MessageCellDelegate) {
self.viewItem = viewItem
self.albumViewWidth = albumViewWidth
self.delegate = delegate
self.textColor = textColor
super.init(frame: CGRect.zero)
setUpViewHierarchy()
}
override init(frame: CGRect) {
preconditionFailure("Use init(text:) instead.")
}
required init?(coder: NSCoder) {
preconditionFailure("Use init(text:) instead.")
}
private func setUpViewHierarchy() {
guard let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0 else { return }
// Body label
let bodyLabel = UILabel()
bodyLabel.numberOfLines = 0
bodyLabel.lineBreakMode = .byTruncatingTail
bodyLabel.text = given(body) { MentionUtilities.highlightMentions(in: $0, threadID: viewItem.interaction.uniqueThreadId) }
bodyLabel.textColor = self.textColor
bodyLabel.font = .systemFont(ofSize: Values.mediumFontSize)
// Content stack view
let contentStackView = UIStackView(arrangedSubviews: [ bodyLabel ])
contentStackView.axis = .horizontal
contentStackView.spacing = Values.smallSpacing
addSubview(contentStackView)
let inset: CGFloat = 12
contentStackView.pin(.left, to: .left, of: self, withInset: inset)
contentStackView.pin(.top, to: .top, of: self)
contentStackView.pin(.right, to: .right, of: self, withInset: -inset)
// Max height
bodyLabel.heightAnchor.constraint(lessThanOrEqualToConstant: MediaTextOverlayView.maxHeight).isActive = true
// Overflow button
let bodyLabelTargetSize = bodyLabel.sizeThatFits(CGSize(width: albumViewWidth - 2 * inset, height: .greatestFiniteMagnitude))
if bodyLabelTargetSize.height > MediaTextOverlayView.maxHeight {
let readMoreButton = UIButton()
self.readMoreButton = readMoreButton
readMoreButton.setTitle("Read More", for: UIControl.State.normal)
readMoreButton.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize)
readMoreButton.setTitleColor(self.textColor, for: UIControl.State.normal)
readMoreButton.addTarget(self, action: #selector(readMore), for: UIControl.Event.touchUpInside)
addSubview(readMoreButton)
readMoreButton.pin(.left, to: .left, of: self, withInset: inset)
readMoreButton.pin(.top, to: .bottom, of: contentStackView, withInset: Values.smallSpacing)
readMoreButton.pin(.bottom, to: .bottom, of: self, withInset: -Values.smallSpacing)
} else {
contentStackView.pin(.bottom, to: .bottom, of: self, withInset: -inset)
}
}
// MARK: Interaction
@objc private func readMore() {
delegate.showFullText(viewItem)
}
}

View File

@ -4,7 +4,6 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
private var previousX: CGFloat = 0 private var previousX: CGFloat = 0
var albumView: MediaAlbumView? var albumView: MediaAlbumView?
var bodyTextView: UITextView? var bodyTextView: UITextView?
var mediaTextOverlayView: MediaTextOverlayView?
// Constraints // Constraints
private lazy var headerViewTopConstraint = headerView.pin(.top, to: .top, of: self, withInset: 1) private lazy var headerViewTopConstraint = headerView.pin(.top, to: .top, of: self, withInset: 1)
private lazy var authorLabelHeightConstraint = authorLabel.set(.height, to: 0) private lazy var authorLabelHeightConstraint = authorLabel.set(.height, to: 0)
@ -313,7 +312,6 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
} }
albumView = nil albumView = nil
bodyTextView = nil bodyTextView = nil
mediaTextOverlayView = nil
let isOutgoing = (viewItem.interaction.interactionType() == .outgoingMessage) let isOutgoing = (viewItem.interaction.interactionType() == .outgoingMessage)
switch viewItem.messageCellType { switch viewItem.messageCellType {
case .textOnlyMessage: case .textOnlyMessage:
@ -325,6 +323,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
snContentView.addSubview(linkPreviewView) snContentView.addSubview(linkPreviewView)
linkPreviewView.pin(to: snContentView) linkPreviewView.pin(to: snContentView)
linkPreviewView.layer.mask = bubbleViewMaskLayer linkPreviewView.layer.mask = bubbleViewMaskLayer
self.bodyTextView = linkPreviewView.bodyTextView
} else if let openGroupInvitationName = message.openGroupInvitationName, let openGroupInvitationURL = message.openGroupInvitationURL { } else if let openGroupInvitationName = message.openGroupInvitationName, let openGroupInvitationURL = message.openGroupInvitationURL {
let openGroupInvitationView = OpenGroupInvitationView(name: openGroupInvitationName, url: openGroupInvitationURL, textColor: bodyLabelTextColor, isOutgoing: isOutgoing) let openGroupInvitationView = OpenGroupInvitationView(name: openGroupInvitationName, url: openGroupInvitationURL, textColor: bodyLabelTextColor, isOutgoing: isOutgoing)
snContentView.addSubview(openGroupInvitationView) snContentView.addSubview(openGroupInvitationView)
@ -373,11 +372,12 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
albumView.layer.mask = bubbleViewMaskLayer albumView.layer.mask = bubbleViewMaskLayer
stackView.addArrangedSubview(albumView) stackView.addArrangedSubview(albumView)
// Body text view // Body text view
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0, 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 inset: CGFloat = 12
let overlayView = MediaTextOverlayView(viewItem: viewItem, albumViewWidth: size.width, textColor: bodyLabelTextColor, delegate: delegate) let maxWidth = size.width - 2 * inset
self.mediaTextOverlayView = overlayView let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, searchText: delegate?.lastSearchedText, delegate: self)
stackView.addArrangedSubview(overlayView) self.bodyTextView = bodyTextView
stackView.addArrangedSubview(UIView(wrapping: bodyTextView, withInsets: UIEdgeInsets(top: 0, left: inset, bottom: inset, right: inset)))
} }
unloadContent = { albumView.unloadMedia() } unloadContent = { albumView.unloadMedia() }
// Constraints // Constraints

View File

@ -106,6 +106,9 @@ class BaseVC : UIViewController {
} }
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
if #available(iOS 13.0, *) {
SNLog("Current trait collection: \(UITraitCollection.current), previous trait collection: \(previousTraitCollection)")
}
if LKAppModeUtilities.isSystemDefault { if LKAppModeUtilities.isSystemDefault {
NotificationCenter.default.post(name: .appModeChanged, object: nil) NotificationCenter.default.post(name: .appModeChanged, object: nil)
} }

View File

@ -48,6 +48,7 @@ public final class OpenGroupPollerV2 : NSObject {
guard let self = self else { return } guard let self = self else { return }
self.isPolling = false self.isPolling = false
bodies.forEach { self.handleCompactPollBody($0, isBackgroundPoll: isBackgroundPoll) } bodies.forEach { self.handleCompactPollBody($0, isBackgroundPoll: isBackgroundPoll) }
SNLog("Open group polling finished for \(self.server).")
seal.fulfill(()) seal.fulfill(())
}.catch(on: OpenGroupAPIV2.workQueue) { error in }.catch(on: OpenGroupAPIV2.workQueue) { error in
SNLog("Open group polling failed due to error: \(error).") SNLog("Open group polling failed due to error: \(error).")

View File

@ -13,14 +13,14 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
// to check if this is the only message request thread (group threads can't be message requests // to check if this is the only message request thread (group threads can't be message requests
// so just ignore those and if the user has hidden message requests then we want to show the // so just ignore those and if the user has hidden message requests then we want to show the
// notification regardless of how many message requests there are) // notification regardless of how many message requests there are)
if !thread.isGroupThread() && thread.isMessageRequest() && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { if !thread.isGroupThread() && thread.isMessageRequest(using: transaction) && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
let threads = transaction.ext(TSThreadDatabaseViewExtensionName) as! YapDatabaseViewTransaction let threads = transaction.ext(TSThreadDatabaseViewExtensionName) as! YapDatabaseViewTransaction
let numMessageRequests = threads.numberOfItems(inGroup: TSMessageRequestGroup) let numMessageRequests = threads.numberOfItems(inGroup: TSMessageRequestGroup)
// Allow this to show a notification if there are no message requests (ie. this is the first one) // Allow this to show a notification if there are no message requests (ie. this is the first one)
guard numMessageRequests == 0 else { return } guard numMessageRequests == 0 else { return }
} }
else if thread.isMessageRequest() && CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { else if thread.isMessageRequest(using: transaction) && CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
// If there are other interactions on this thread already then don't show the notification // If there are other interactions on this thread already then don't show the notification
if thread.numberOfInteractions(with: transaction) > 1 { return } if thread.numberOfInteractions(with: transaction) > 1 { return }
@ -37,7 +37,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
} }
let context = Contact.context(for: thread) let context = Contact.context(for: thread)
let senderName = Storage.shared.getContact(with: senderPublicKey)?.displayName(for: context) ?? senderPublicKey let senderName = Storage.shared.getContact(with: senderPublicKey, using: transaction)?.displayName(for: context) ?? senderPublicKey
var notificationTitle = senderName var notificationTitle = senderName
if let group = thread as? TSGroupThread { if let group = thread as? TSGroupThread {
@ -85,7 +85,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
// If it's a message request then overwrite the body to be something generic (only show a notification // If it's a message request then overwrite the body to be something generic (only show a notification
// when receiving a new message request if there aren't any others or the user had hidden them) // when receiving a new message request if there aren't any others or the user had hidden them)
if thread.isMessageRequest() { if thread.isMessageRequest(using: transaction) {
notificationContent.title = "Session" notificationContent.title = "Session"
notificationContent.body = "MESSAGE_REQUESTS_NOTIFICATION".localized() notificationContent.body = "MESSAGE_REQUESTS_NOTIFICATION".localized()
} }
@ -93,8 +93,16 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
// Add request // Add request
let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString
let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil) let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil)
SNLog("Add remote notification request") SNLog("Add remote notification request: \(notificationContent.body)")
UNUserNotificationCenter.current().add(request) let semaphore = DispatchSemaphore(value: 0)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
SNLog("Failed to add notification request due to error:\(error)")
}
semaphore.signal()
}
semaphore.wait()
SNLog("Finish adding remote notification request")
} }
public func cancelNotification(_ identifier: String) { public func cancelNotification(_ identifier: String) {

View File

@ -41,7 +41,10 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
let envelope = try? MessageWrapper.unwrap(data: data), let envelopeAsData = try? envelope.serializedData() else { let envelope = try? MessageWrapper.unwrap(data: data), let envelopeAsData = try? envelope.serializedData() else {
return self.handleFailure(for: notificationContent) return self.handleFailure(for: notificationContent)
} }
Storage.write { transaction in // Intentionally capture self // HACK: It is important to use writeSync() here to avoid a race condition
// where the completeSilenty() is called before the local notification request
// is added to notification center.
Storage.writeSync { transaction in // Intentionally capture self
do { do {
let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction) let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction)
switch message { switch message {

View File

@ -204,7 +204,11 @@ public enum OnionRequestAPI {
} else { } else {
return buildPaths(reusing: []).map2 { paths in return buildPaths(reusing: []).map2 { paths in
if let snode = snode { if let snode = snode {
return paths.filter { !$0.contains(snode) }.randomElement()! if let path = paths.filter({ !$0.contains(snode) }).randomElement() {
return path
} else {
throw Error.insufficientSnodes
}
} else { } else {
return paths.randomElement()! return paths.randomElement()!
} }