minor improvements to reduce the database read on UI thread

pull/541/head
Ryan Zhao 3 years ago
parent 936fbd27c2
commit 2ae0ae40d4

@ -11,6 +11,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
let threadStartedAsMessageRequest: Bool
let focusedMessageID: String? // This is used for global search
var focusedMessageIndexPath: IndexPath?
var initialUnreadCount: UInt = 0
var unreadViewItems: [ConversationViewItem] = []
var scrollButtonBottomConstraint: NSLayoutConstraint?
var scrollButtonMessageRequestsBottomConstraint: NSLayoutConstraint?
@ -276,11 +277,10 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
self.threadStartedAsMessageRequest = thread.isMessageRequest()
self.focusedMessageID = focusedMessageID
super.init(nibName: nil, bundle: nil)
var unreadCount: UInt = 0
Storage.read { transaction in
unreadCount = self.thread.unreadMessageCount(transaction: transaction)
self.initialUnreadCount = self.thread.unreadMessageCount(transaction: transaction)
}
let clampedUnreadCount = min(unreadCount, UInt(kConversationInitialMaxRangeSize), UInt(viewItems.endIndex))
let clampedUnreadCount = min(self.initialUnreadCount, UInt(kConversationInitialMaxRangeSize), UInt(viewItems.endIndex))
unreadViewItems = clampedUnreadCount != 0 ? [ConversationViewItem](viewItems[viewItems.endIndex - Int(clampedUnreadCount) ..< viewItems.endIndex]) : []
}
@ -289,6 +289,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
}
override func viewDidLoad() {
SNLog("Ryan: Conversation VC starts loading at \(NSDate.ows_millisecondTimeStamp())")
super.viewDidLoad()
// Gradient
setUpGradientBackground()
@ -391,27 +392,26 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
if let v2OpenGroup = Storage.shared.getV2OpenGroup(for: thread.uniqueId!) {
OpenGroupAPIV2.getMemberCount(for: v2OpenGroup.room, on: v2OpenGroup.server).retainUntilComplete()
}
SNLog("Ryan: Conversation VC ends loading at \(NSDate.ows_millisecondTimeStamp())")
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !didFinishInitialLayout {
// Scroll to the last unread message if possible; otherwise scroll to the bottom.
var unreadCount: UInt = 0
Storage.read { transaction in
unreadCount = self.thread.unreadMessageCount(transaction: transaction)
}
// When the unread message count is more than the number of view items of a page,
// the screen will scroll to the bottom instead of the first unread message.
// unreadIndicatorIndex is calculated during loading of the viewItems, so it's
// supposed to be accurate.
DispatchQueue.main.async {
SNLog("Ryan: Conversation VC starts layout subviews at \(NSDate.ows_millisecondTimeStamp())")
if let focusedMessageID = self.focusedMessageID {
self.scrollToInteraction(with: focusedMessageID, isAnimated: false, highlighted: true)
} else {
let firstUnreadMessageIndex = self.viewModel.viewState.unreadIndicatorIndex?.intValue
?? (self.viewItems.count - self.unreadViewItems.count)
if unreadCount > 0, let viewItem = self.viewItems[ifValid: firstUnreadMessageIndex], let interactionID = viewItem.interaction.uniqueId {
if self.initialUnreadCount > 0, let viewItem = self.viewItems[ifValid: firstUnreadMessageIndex], let interactionID = viewItem.interaction.uniqueId {
self.scrollToInteraction(with: interactionID, position: .top, isAnimated: false)
self.unreadCountView.alpha = self.scrollButton.alpha
} else {
@ -419,11 +419,13 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
}
}
self.scrollButton.alpha = self.getScrollButtonOpacity()
SNLog("Ryan: Conversation VC ends layout subviews at \(NSDate.ows_millisecondTimeStamp())")
}
}
}
override func viewDidAppear(_ animated: Bool) {
SNLog("Ryan: Conversation VC did appear at \(NSDate.ows_millisecondTimeStamp())")
super.viewDidAppear(animated)
highlightFocusedMessageIfNeeded()
didFinishInitialLayout = true
@ -777,6 +779,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
let isMainAppAndActive = CurrentAppContext().isMainAppAndActive
guard isMainAppAndActive && viewModel.canLoadMoreItems() && !isLoadingMore
&& messagesTableView.contentOffset.y < ConversationVC.loadMoreThreshold else { return }
print("Ryan: auto loading more")
isLoadingMore = true
viewModel.loadAnotherPageOfMessages()
}

@ -1,6 +1,7 @@
final class QuoteView : UIView {
private let mode: Mode
private let thread: TSThread
private let direction: Direction
private let hInset: CGFloat
private let maxWidth: CGFloat
@ -34,25 +35,6 @@ final class QuoteView : UIView {
}
}
private var threadID: String {
switch mode {
case .regular(let viewItem): return viewItem.interaction.uniqueThreadId
case .draft(let model): return model.threadId
}
}
private var isGroupThread: Bool {
switch mode {
case .regular(let viewItem): return viewItem.isGroupThread
case .draft(let model):
var result = false
Storage.read { transaction in
result = TSThread.fetch(uniqueId: model.threadId, transaction: transaction)?.isGroupThread() ?? false
}
return result
}
}
private var authorID: String {
switch mode {
case .regular(let viewItem): return viewItem.quotedReply!.authorId
@ -93,8 +75,9 @@ final class QuoteView : UIView {
static let cancelButtonSize: CGFloat = 33
// MARK: Lifecycle
init(for viewItem: ConversationViewItem, direction: Direction, hInset: CGFloat, maxWidth: CGFloat) {
init(for viewItem: ConversationViewItem, in thread: TSThread?, direction: Direction, hInset: CGFloat, maxWidth: CGFloat) {
self.mode = .regular(viewItem)
self.thread = thread ?? TSThread.fetch(uniqueId: viewItem.interaction.uniqueThreadId)!
self.maxWidth = maxWidth
self.direction = direction
self.hInset = hInset
@ -105,6 +88,7 @@ final class QuoteView : UIView {
init(for model: OWSQuotedReplyModel, direction: Direction, hInset: CGFloat, maxWidth: CGFloat, delegate: QuoteViewDelegate) {
self.mode = .draft(model)
self.thread = TSThread.fetch(uniqueId: model.threadId)!
self.maxWidth = maxWidth
self.direction = direction
self.hInset = hInset
@ -188,16 +172,15 @@ final class QuoteView : UIView {
bodyLabel.lineBreakMode = .byTruncatingTail
let isOutgoing = (direction == .outgoing)
bodyLabel.font = .systemFont(ofSize: Values.smallFontSize)
bodyLabel.attributedText = given(body) { MentionUtilities.highlightMentions(in: $0, isOutgoingMessage: isOutgoing, threadID: threadID, attributes: [:]) }
?? given(attachments.first?.contentType) { NSAttributedString(string: MIMETypeUtil.isAudio($0) ? "Audio" : "Document") } ?? NSAttributedString(string: "Document")
bodyLabel.attributedText = given(body) { MentionUtilities.highlightMentions(in: $0, isOutgoingMessage: isOutgoing, threadID: thread.uniqueId!, attributes: [:]) } ?? given(attachments.first?.contentType) { NSAttributedString(string: MIMETypeUtil.isAudio($0) ? "Audio" : "Document") } ?? NSAttributedString(string: "Document")
bodyLabel.textColor = textColor
let bodyLabelSize = bodyLabel.systemLayoutSizeFitting(availableSpace)
// Label stack view
var authorLabelHeight: CGFloat?
if isGroupThread {
if let groupThread = thread as? TSGroupThread {
let authorLabel = UILabel()
authorLabel.lineBreakMode = .byTruncatingTail
let context: Contact.Context = (TSGroupThread.fetch(uniqueId: threadID)?.isOpenGroup == true) ? .openGroup : .regular
let context: Contact.Context = groupThread.isOpenGroup ? .openGroup : .regular
authorLabel.text = Storage.shared.getContact(with: authorID)?.displayName(for: context) ?? authorID
authorLabel.textColor = textColor
authorLabel.font = .boldSystemFont(ofSize: Values.smallFontSize)
@ -225,7 +208,7 @@ final class QuoteView : UIView {
// Constraints
contentView.addSubview(mainStackView)
mainStackView.pin(to: contentView)
if !isGroupThread {
if !thread.isGroupThread() {
bodyLabel.set(.width, to: bodyLabelSize.width)
}
let bodyLabelHeight = bodyLabelSize.height.clamp(0, maxBodyLabelHeight)

@ -335,7 +335,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
if viewItem.quotedReply != nil {
let direction: QuoteView.Direction = isOutgoing ? .outgoing : .incoming
let hInset: CGFloat = 2
let quoteView = QuoteView(for: viewItem, direction: direction, hInset: hInset, maxWidth: maxWidth)
let quoteView = QuoteView(for: viewItem, in: thread, direction: direction, hInset: hInset, maxWidth: maxWidth)
let quoteViewContainer = UIView(wrapping: quoteView, withInsets: UIEdgeInsets(top: 0, leading: hInset, bottom: 0, trailing: hInset))
stackView.addArrangedSubview(quoteViewContainer)
}

Loading…
Cancel
Save