Add additional logic to filter the race condition while navigating to a message

This commit is contained in:
Ali 2021-02-16 16:33:10 +04:00
parent 7aa3c20140
commit 2c6c7e23d6

View File

@ -128,6 +128,7 @@ struct ChatHistoryView {
let associatedData: ChatMessageItemAssociatedData
let lastHeaderId: Int64
let id: Int32
let locationInput: ChatHistoryLocationInput?
}
enum ChatHistoryViewTransitionReason {
@ -705,7 +706,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let currentViewVersion = Atomic<Int?>(value: nil)
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int), NoError>
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?), NoError>
var isFirstTime = true
if case let .custom(messages, at, _) = source {
historyViewUpdate = messages
@ -726,7 +727,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
scrollPosition = nil
}
return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version)
return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version, nil)
}
} else {
historyViewUpdate = self.chatHistoryLocationPromise.get()
@ -741,16 +742,16 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
break
}
}
}
|> map { view -> (ChatHistoryViewUpdate, Int) in
let version = currentViewVersion.modify({ value in
if let value = value {
return value + 1
} else {
return 0
}
})!
return (view, version)
|> map { view -> (ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?) in
let version = currentViewVersion.modify({ value in
if let value = value {
return value + 1
} else {
return 0
}
})!
return (view, version, location)
}
}
}
@ -875,6 +876,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
func applyHole() {
Queue.mainQueue().async {
if let strongSelf = self {
if update.2 != strongSelf.chatHistoryLocationValue {
return
}
let historyView = (strongSelf.opaqueTransactionState as? ChatHistoryTransactionOpaqueState)?.historyView
let displayRange = strongSelf.displayedItemRange
if let filteredEntries = historyView?.filteredEntries, let visibleRange = displayRange.visibleRange {
@ -954,7 +959,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let filteredEntries = chatHistoryEntriesForView(location: chatLocation, view: view, includeUnreadEntry: mode == .bubbles, includeEmptyEntry: mode == .bubbles && tagMask == nil, includeChatInfoEntry: mode == .bubbles, includeSearchEntry: includeSearchEntry && tagMask != nil, reverse: reverse, groupMessages: mode == .bubbles, selectedMessages: selectedMessages, presentationData: chatPresentationData, historyAppearsCleared: historyAppearsCleared, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, pendingRemovedMessages: pendingRemovedMessages, associatedData: associatedData, updatingMedia: updatingMedia, customChannelDiscussionReadState: customChannelDiscussionReadState, customThreadOutgoingReadState: customThreadOutgoingReadState)
let lastHeaderId = filteredEntries.last.flatMap { listMessageDateHeaderId(timestamp: $0.index.timestamp) } ?? 0
let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id)
let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id, locationInput: update.2)
let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages))
let previous = previousValueAndVersion?.0
let previousSelectedMessages = previousValueAndVersion?.2
@ -1476,7 +1481,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
}
} else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = self.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount, highlight: false), id: self.takeNextHistoryLocationId())
if self.chatHistoryLocationValue == historyView.locationInput {
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount, highlight: false), id: self.takeNextHistoryLocationId())
}
} else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil {
let locationInput: ChatHistoryLocation = .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount, highlight: false)
if self.chatHistoryLocationValue?.content != locationInput {