Merge pull request #557 from RyanRory/1.11.21

Fix bugs and crashes for 1.11.21
pull/561/head
RyanZhao 3 years ago committed by GitHub
commit a12ff0cbe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -113,7 +113,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
let result = UIView()
result.backgroundColor = Colors.text.withAlphaComponent(Values.veryLowOpacity)
let size = ConversationVC.unreadCountViewSize
result.set(.width, to: size)
result.set(.width, greaterThanOrEqualTo: size)
result.set(.height, to: size)
result.layer.masksToBounds = true
result.layer.cornerRadius = size / 2
@ -193,7 +193,10 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
// Unread count view
view.addSubview(unreadCountView)
unreadCountView.addSubview(unreadCountLabel)
unreadCountLabel.pin(to: unreadCountView)
unreadCountLabel.pin(.top, to: .top, of: unreadCountView)
unreadCountLabel.pin(.bottom, to: .bottom, of: unreadCountView)
unreadCountView.pin(.leading, to: .leading, of: unreadCountLabel, withInset: -4)
unreadCountView.pin(.trailing, to: .trailing, of: unreadCountLabel, withInset: 4)
unreadCountView.centerYAnchor.constraint(equalTo: scrollButton.topAnchor).isActive = true
unreadCountView.center(.horizontal, in: scrollButton)
updateUnreadCountView()
@ -473,6 +476,10 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
func scrollToBottom(isAnimated: Bool) {
guard !isUserScrolling else { return }
if let interactionID = viewItems.last?.interaction.uniqueId {
self.scrollToInteraction(with: interactionID, position: .top, isAnimated: isAnimated)
return
}
// Ensure the view is fully up to date before we try to scroll to the bottom, since
// we use the table view's bounds to determine where the bottom is.
view.layoutIfNeeded()
@ -503,8 +510,8 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
unreadViewItems.remove(at: index)
}
let unreadCount = unreadViewItems.count
unreadCountLabel.text = unreadCount < 100 ? "\(unreadCount)" : "99+"
let fontSize = (unreadCount < 100) ? Values.verySmallFontSize : 8
unreadCountLabel.text = unreadCount < 10000 ? "\(unreadCount)" : "9999+"
let fontSize = (unreadCount < 10000) ? Values.verySmallFontSize : 8
unreadCountLabel.font = .boldSystemFont(ofSize: fontSize)
unreadCountView.isHidden = (unreadCount == 0)
}

@ -567,13 +567,13 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
TSAttachment *_Nullable linkPreviewAttachment =
[TSAttachment fetchObjectWithUniqueID:message.linkPreview.imageAttachmentId transaction:transaction];
if (!linkPreviewAttachment) {
OWSFailDebug(@"Could not load link preview image attachment.");
OWSLogDebug(@"Could not load link preview image attachment.");
} else if (!linkPreviewAttachment.isImage) {
OWSFailDebug(@"Link preview attachment isn't an image.");
OWSLogDebug(@"Link preview attachment isn't an image.");
} else if ([linkPreviewAttachment isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *attachmentStream = (TSAttachmentStream *)linkPreviewAttachment;
if (!attachmentStream.isValidImage) {
OWSFailDebug(@"Link preview image attachment isn't valid.");
OWSLogDebug(@"Link preview image attachment isn't valid.");
} else {
self.linkPreviewAttachment = linkPreviewAttachment;
}

@ -56,7 +56,7 @@ final class MediaTextOverlayView : UIView {
self.readMoreButton = readMoreButton
readMoreButton.setTitle("Read More", for: UIControl.State.normal)
readMoreButton.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize)
readMoreButton.setTitleColor(.white, for: UIControl.State.normal)
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)

@ -131,6 +131,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
private var bodyLabelTextColor: UIColor {
switch (direction, AppModeManager.shared.currentAppMode) {
case (.outgoing, .dark), (.incoming, .light): return .black
case (.outgoing, .light): return Colors.grey
default: return .white
}
}
@ -207,8 +208,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
// MARK: Updating
override func update() {
guard let viewItem = viewItem, let message = viewItem.interaction as? TSMessage else { return }
let thread = message.thread
let isGroupThread = thread.isGroupThread()
let isGroupThread = viewItem.isGroupThread
// Profile picture view
profilePictureViewLeftConstraint.constant = isGroupThread ? VisibleMessageCell.groupThreadHSpacing : 0
profilePictureViewWidthConstraint.constant = isGroupThread ? VisibleMessageCell.profilePictureSize : 0
@ -217,8 +217,8 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
if let senderSessionID = senderSessionID {
profilePictureView.update(for: senderSessionID)
}
if let thread = thread as? TSGroupThread, thread.isOpenGroup, let senderSessionID = senderSessionID {
if let openGroupV2 = Storage.shared.getV2OpenGroup(for: thread.uniqueId!) {
if let senderSessionID = senderSessionID, message.isOpenGroupMessage {
if let openGroupV2 = Storage.shared.getV2OpenGroup(for: message.uniqueThreadId) {
let isUserModerator = OpenGroupAPIV2.isUserModerator(senderSessionID, for: openGroupV2.room, on: openGroupV2.server)
moderatorIconImageView.isHidden = !isUserModerator || profilePictureView.isHidden
} else {
@ -639,8 +639,15 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
let maxAspectRatio = 1 / minAspectRatio
aspectRatio = aspectRatio.clamp(minAspectRatio, maxAspectRatio)
let maxSize = CGSize(width: maxMessageWidth, height: maxMessageWidth)
var width = with(maxSize.height * aspectRatio) { $0 > maxSize.width ? maxSize.width : $0 }
var height = (width > maxSize.width) ? (maxSize.width / aspectRatio) : maxSize.height
var width: CGFloat
var height: CGFloat
if aspectRatio > 1 {
width = maxSize.width
height = width / aspectRatio
} else {
height = maxSize.height
width = height * aspectRatio
}
// Don't blow up small images unnecessarily
let minSize: CGFloat = 150
let shortSourceDimension = min(size.width, size.height)

@ -601,6 +601,8 @@
"light_mode_theme" = "Light";
"PIN_BUTTON_TEXT" = "Pin";
"UNPIN_BUTTON_TEXT" = "Unpin";
"meida_saved" = "Media saved by %@.";
"screenshot_taken" = "%@ took a screenshot.";
"SEARCH_SECTION_CONTACTS" = "Contacts and Groups";
"SEARCH_SECTION_MESSAGES" = "Messages";
"SEARCH_SECTION_RECENT" = "Recent";

@ -143,7 +143,7 @@ final class JoinOpenGroupVC : BaseVC, UIPageViewControllerDataSource, UIPageView
Storage.shared.write { transaction in
OpenGroupManagerV2.shared.add(room: room, server: server, publicKey: publicKey, using: transaction)
.done(on: DispatchQueue.main) { [weak self] _ in
self?.presentingViewController!.dismiss(animated: true, completion: nil)
self?.presentingViewController?.dismiss(animated: true, completion: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
}

@ -28,7 +28,7 @@ final class ConversationCell : UITableViewCell {
let result = UIView()
result.backgroundColor = Colors.text.withAlphaComponent(Values.veryLowOpacity)
let size = ConversationCell.unreadCountViewSize
result.set(.width, to: size)
result.set(.width, greaterThanOrEqualTo: size)
result.set(.height, to: size)
result.layer.masksToBounds = true
result.layer.cornerRadius = size / 2
@ -150,7 +150,9 @@ final class ConversationCell : UITableViewCell {
profilePictureView.size = profilePictureViewSize
// Unread count view
unreadCountView.addSubview(unreadCountLabel)
unreadCountLabel.pin(to: unreadCountView)
unreadCountLabel.pin([ VerticalEdge.top, VerticalEdge.bottom ], to: unreadCountView)
unreadCountView.pin(.leading, to: .leading, of: unreadCountLabel, withInset: -4)
unreadCountView.pin(.trailing, to: .trailing, of: unreadCountLabel, withInset: 4)
// Has mention view
hasMentionView.addSubview(hasMentionLabel)
hasMentionLabel.pin(to: hasMentionView)
@ -293,8 +295,8 @@ final class ConversationCell : UITableViewCell {
isPinnedIcon.isHidden = !threadViewModel.isPinned
unreadCountView.isHidden = !threadViewModel.hasUnreadMessages
let unreadCount = threadViewModel.unreadCount
unreadCountLabel.text = unreadCount < 100 ? "\(unreadCount)" : "99+"
let fontSize = (unreadCount < 100) ? Values.verySmallFontSize : 8
unreadCountLabel.text = unreadCount < 10000 ? "\(unreadCount)" : "9999+"
let fontSize = (unreadCount < 10000) ? Values.verySmallFontSize : 8
unreadCountLabel.font = .boldSystemFont(ofSize: fontSize)
hasMentionView.isHidden = !(threadViewModel.hasUnreadMentions && thread.isGroupThread())
profilePictureView.update(for: thread)

@ -155,31 +155,10 @@ NS_ASSUME_NONNULL_BEGIN
if (_read && readTimestamp >= self.expireStartedAt) {
return;
}
BOOL isTrusted = YES;
TSThread* thread = [self threadWithTransaction:transaction];
if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread* contactThread = (TSContactThread*)thread;
isTrusted = [[LKStorage shared] getContactWithSessionID:[contactThread contactSessionID] using:transaction].isTrusted;
}
BOOL areAllAttachmentsDownloaded = YES;
if (isTrusted) {
for (NSString *attachmentId in self.attachmentIds) {
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
// If the attachment download failed, we can mark this message as read.
// Otherwise, this message will never be marked as read.
if ([attachment isKindOfClass:[TSAttachmentPointer class]]
&& ((TSAttachmentPointer *)attachment).state == TSAttachmentPointerStateFailed) {
continue;
}
areAllAttachmentsDownloaded = areAllAttachmentsDownloaded && attachment.isDownloaded;
if (!areAllAttachmentsDownloaded) break;
}
}
if (!areAllAttachmentsDownloaded) {
return;
}
// We just ignore all attachments download state here and mark all messages as read
// This is a workaround for a situation that some large attachments won't be downloaded
// and just stuck in a downloading state. In that case, the corresponding message won't
// be able to be marked as read.
_read = YES;
[self saveWithTransaction:transaction];

@ -19,10 +19,10 @@ final class DataExtractionNotificationInfoMessage : TSInfoMessage {
let sessionID = thread.contactSessionID()
let displayName = Storage.shared.getContact(with: sessionID)?.displayName(for: .regular) ?? sessionID
switch messageType {
case .screenshotNotification: return "\(displayName) took a screenshot."
case .screenshotNotification: return String(format: NSLocalizedString("screenshot_taken", comment: ""), displayName)
case .mediaSavedNotification:
// TODO: Use referencedAttachmentTimestamp to tell the user * which * media was saved
return "Media saved by \(displayName)."
return String(format: NSLocalizedString("meida_saved", comment: ""), displayName)
default: preconditionFailure()
}
}

@ -44,7 +44,7 @@ public final class ClosedGroupPoller : NSObject {
// Might be a race condition that the setUpPolling finishes too soon,
// and the timer is not created, if we mark the group as is polling
// after setUpPolling. So the poller may not work, thus misses messages.
isPolling[groupPublicKey] = true
internalQueue.sync{ isPolling[groupPublicKey] = true }
setUpPolling(for: groupPublicKey)
}
@ -55,7 +55,7 @@ public final class ClosedGroupPoller : NSObject {
}
public func stopPolling(for groupPublicKey: String) {
isPolling[groupPublicKey] = false
internalQueue.sync{ isPolling[groupPublicKey] = false }
timers[groupPublicKey]?.invalidate()
}

@ -13,6 +13,7 @@ import UIKit
@objc(LKColors)
public final class Colors : NSObject {
@objc public static var grey: UIColor { UIColor(named: "session_grey")! }
@objc public static var accent: UIColor { UIColor(named: "session_accent")! }
@objc public static var text: UIColor { UIColor(named: "session_text")! }
@objc public static var destructive: UIColor { UIColor(named: "session_destructive")! }

@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x30",
"green" : "0x2F",
"red" : "0x31"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -95,4 +95,17 @@ public extension UIView {
constraint.isActive = true
return constraint
}
@discardableResult
func set(_ dimension: Dimension, greaterThanOrEqualTo size: CGFloat) -> NSLayoutConstraint {
translatesAutoresizingMaskIntoConstraints = false
let constraint: NSLayoutConstraint = {
switch dimension {
case .width: return widthAnchor.constraint(greaterThanOrEqualToConstant: size)
case .height: return heightAnchor.constraint(greaterThanOrEqualToConstant: size)
}
}()
constraint.isActive = true
return constraint
}
}

Loading…
Cancel
Save