diff --git a/submodules/Postbox/Sources/MessageHistoryView.swift b/submodules/Postbox/Sources/MessageHistoryView.swift index 156842d538..5f3e78ee15 100644 --- a/submodules/Postbox/Sources/MessageHistoryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryView.swift @@ -645,27 +645,27 @@ final class MutableMessageHistoryView { } } - func firstHole() -> (MessageHistoryViewHole, MessageHistoryViewRelativeHoleDirection)? { + func firstHole() -> (MessageHistoryViewHole, MessageHistoryViewRelativeHoleDirection, Int)? { switch self.sampledState { - case let .loading(loadingSample): - switch loadingSample { - case .ready: - return nil - case let .loadHole(peerId, namespace, _, id): - return (.peer(MessageHistoryViewPeerHole(peerId: peerId, namespace: namespace)), .aroundId(MessageId(peerId: peerId, namespace: namespace, id: id))) - } - case let .loaded(loadedSample): - if let hole = loadedSample.hole { - let direction: MessageHistoryViewRelativeHoleDirection - if let endId = hole.endId { - direction = .range(start: MessageId(peerId: hole.peerId, namespace: hole.namespace, id: hole.startId), end: MessageId(peerId: hole.peerId, namespace: hole.namespace, id: endId)) - } else { - direction = .aroundId(MessageId(peerId: hole.peerId, namespace: hole.namespace, id: hole.startId)) - } - return (.peer(MessageHistoryViewPeerHole(peerId: hole.peerId, namespace: hole.namespace)), direction) + case let .loading(loadingSample): + switch loadingSample { + case .ready: + return nil + case let .loadHole(peerId, namespace, _, id): + return (.peer(MessageHistoryViewPeerHole(peerId: peerId, namespace: namespace)), .aroundId(MessageId(peerId: peerId, namespace: namespace, id: id)), self.fillCount * 2) + } + case let .loaded(loadedSample): + if let hole = loadedSample.hole { + let direction: MessageHistoryViewRelativeHoleDirection + if let endId = hole.endId { + direction = .range(start: MessageId(peerId: hole.peerId, namespace: hole.namespace, id: hole.startId), end: MessageId(peerId: hole.peerId, namespace: hole.namespace, id: endId)) } else { - return nil + direction = .aroundId(MessageId(peerId: hole.peerId, namespace: hole.namespace, id: hole.startId)) } + return (.peer(MessageHistoryViewPeerHole(peerId: hole.peerId, namespace: hole.namespace)), direction, self.fillCount * 2) + } else { + return nil + } } } } diff --git a/submodules/Postbox/Sources/MessageHistoryViewState.swift b/submodules/Postbox/Sources/MessageHistoryViewState.swift index c00bb54ef6..37de8f9ff2 100644 --- a/submodules/Postbox/Sources/MessageHistoryViewState.swift +++ b/submodules/Postbox/Sources/MessageHistoryViewState.swift @@ -321,17 +321,6 @@ private func sampleHoleRanges(orderedEntriesBySpace: [PeerIdAndNamespace: Ordere } } - for item in items.lowerOrAtAnchor { - if item.index.id.id == 76891 { - assert(true) - } - } - for item in items.higherThanAnchor { - if item.index.id.id == 76891 { - assert(true) - } - } - var lowerOrAtAnchorHole: (distanceFromAnchor: Int, hole: SampledHistoryViewHole)? for i in (-1 ..< items.lowerOrAtAnchor.count).reversed() { @@ -500,103 +489,6 @@ private func sampleHoleRanges(orderedEntriesBySpace: [PeerIdAndNamespace: Ordere sampledHole = (chosenHole.distanceFromAnchor, chosenHole.hole) } } - - /*let anchorIndex = binaryIndexOrLower(items.entries, anchor) - let anchorStartingMessageId: MessageId.Id - if anchorIndex == -1 { - anchorStartingMessageId = 1 - } else { - anchorStartingMessageId = items.entries[anchorIndex].index.id.id - } - - let startingLowerDirectionIndex = anchorIndex - let startingHigherDirectionIndex = anchorIndex + 1 - - var lowerDirectionIndex = startingLowerDirectionIndex - var higherDirectionIndex = startingHigherDirectionIndex - while lowerDirectionIndex >= 0 || higherDirectionIndex < items.entries.count { - if lowerDirectionIndex >= 0 { - let itemIndex = items.entries[lowerDirectionIndex].index - var itemBoundaryMessageId: MessageId.Id = itemIndex.id.id - if lowerDirectionIndex == 0 && itemBoundaryMessageId == bounds.lower.id.id { - itemBoundaryMessageId = 1 - } - let previousBoundaryIndex: MessageIndex - if lowerDirectionIndex == startingLowerDirectionIndex { - previousBoundaryIndex = itemIndex - } else { - previousBoundaryIndex = items.entries[lowerDirectionIndex + 1].index - } - let toLowerRange: ClosedRange = min(Int(anchorStartingMessageId), Int(itemBoundaryMessageId)) ... max(Int(anchorStartingMessageId), Int(itemBoundaryMessageId)) - if indices.intersects(integersIn: toLowerRange) { - var itemClipIndex: MessageIndex - if indices.contains(Int(previousBoundaryIndex.id.id)) { - itemClipIndex = previousBoundaryIndex - } else { - itemClipIndex = previousBoundaryIndex.predecessor() - } - clipRanges.append(MessageIndex.absoluteLowerBound() ... itemClipIndex) - var replaceHole = false - if let (currentItemIndex, _) = sampledHole { - if let currentItemIndex = currentItemIndex, abs(lowerDirectionIndex - anchorIndex) < abs(currentItemIndex - anchorIndex) { - replaceHole = true - } - } else { - replaceHole = true - } - - if replaceHole { - if let idInHole = indices.integerLessThanOrEqualTo(toLowerRange.upperBound) { - sampledHole = (lowerDirectionIndex, SampledHistoryViewHole(peerId: space.peerId, namespace: space.namespace, tag: tag, indices: indices, startId: MessageId.Id(idInHole), endId: 1)) - } else { - assertionFailure() - } - } - lowerDirectionIndex = -1 - } - } - lowerDirectionIndex -= 1 - - if higherDirectionIndex < items.entries.count { - let itemIndex = items.entries[higherDirectionIndex].index - var itemBoundaryMessageId: MessageId.Id = itemIndex.id.id - if higherDirectionIndex == items.entries.count - 1 && itemBoundaryMessageId == bounds.upper.id.id { - itemBoundaryMessageId = Int32.max - 1 - } - let previousBoundaryIndex: MessageIndex - if higherDirectionIndex == startingHigherDirectionIndex { - previousBoundaryIndex = itemIndex - } else { - previousBoundaryIndex = items.entries[higherDirectionIndex - 1].index - } - let toHigherRange: ClosedRange = min(Int(anchorStartingMessageId), Int(itemBoundaryMessageId)) ... max(Int(anchorStartingMessageId), Int(itemBoundaryMessageId)) - if indices.intersects(integersIn: toHigherRange) { - var itemClipIndex: MessageIndex - if indices.contains(Int(previousBoundaryIndex.id.id)) { - itemClipIndex = previousBoundaryIndex - } else { - itemClipIndex = previousBoundaryIndex.successor() - } - clipRanges.append(itemClipIndex ... MessageIndex.absoluteUpperBound()) - var replaceHole = false - if let (currentItemIndex, _) = sampledHole { - if let currentItemIndex = currentItemIndex, abs(higherDirectionIndex - anchorIndex) < abs(currentItemIndex - anchorIndex) { - replaceHole = true - } - } else { - replaceHole = true - } - - if replaceHole { - if let idInHole = indices.integerGreaterThanOrEqualTo(toHigherRange.lowerBound) { - sampledHole = (higherDirectionIndex, SampledHistoryViewHole(peerId: space.peerId, namespace: space.namespace, tag: tag, indices: indices, startId: MessageId.Id(idInHole), endId: Int32.max - 1)) - } - } - higherDirectionIndex = items.entries.count - } - } - higherDirectionIndex += 1 - }*/ } return (clipRanges, sampledHole?.hole) } diff --git a/submodules/Postbox/Sources/MessageOfInterestHolesView.swift b/submodules/Postbox/Sources/MessageOfInterestHolesView.swift index b07fe3c366..b27872d4a1 100644 --- a/submodules/Postbox/Sources/MessageOfInterestHolesView.swift +++ b/submodules/Postbox/Sources/MessageOfInterestHolesView.swift @@ -37,28 +37,30 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView { self.location = location self.count = count - var peerId: PeerId + let mainPeerId: PeerId + let peerIds: MessageHistoryViewPeerIds switch self.location { - case let .peer(id): - peerId = id + case let .peer(id): + mainPeerId = id + peerIds = postbox.peerIdsForLocation(.peer(id), tagMask: nil) } var anchor: HistoryViewInputAnchor = .upperBound - if let combinedState = postbox.readStateTable.getCombinedState(peerId), let state = combinedState.states.first, state.1.count != 0 { + if let combinedState = postbox.readStateTable.getCombinedState(mainPeerId), let state = combinedState.states.first, state.1.count != 0 { switch state.1 { - case let .idBased(maxIncomingReadId, _, _, _, _): - anchor = .message(MessageId(peerId: peerId, namespace: state.0, id: maxIncomingReadId)) - case let .indexBased(maxIncomingReadIndex, _, _, _): - anchor = .index(maxIncomingReadIndex) + case let .idBased(maxIncomingReadId, _, _, _, _): + anchor = .message(MessageId(peerId: mainPeerId, namespace: state.0, id: maxIncomingReadId)) + case let .indexBased(maxIncomingReadIndex, _, _, _): + anchor = .index(maxIncomingReadIndex) } } self.anchor = anchor - self.wrappedView = MutableMessageHistoryView(postbox: postbox, orderStatistics: [], peerIds: .single(peerId), anchor: self.anchor, combinedReadStates: nil, transientReadStates: nil, tag: nil, namespaces: .all, count: self.count, topTaggedMessages: [:], additionalDatas: [], getMessageCountInRange: { _, _ in return 0}) + self.wrappedView = MutableMessageHistoryView(postbox: postbox, orderStatistics: [], peerIds: peerIds, anchor: self.anchor, combinedReadStates: nil, transientReadStates: nil, tag: nil, namespaces: .all, count: self.count, topTaggedMessages: [:], additionalDatas: [], getMessageCountInRange: { _, _ in return 0}) let _ = self.updateFromView() } private func updateFromView() -> Bool { let closestHole: MessageOfInterestHole? - if let (hole, direction) = self.wrappedView.firstHole() { + if let (hole, direction, _) = self.wrappedView.firstHole() { closestHole = MessageOfInterestHole(hole: hole, direction: direction) } else { closestHole = nil @@ -66,26 +68,26 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView { var closestLaterMedia: [HolesViewMedia] = [] switch self.wrappedView.sampledState { - case .loading: - break - case let .loaded(sample): - switch sample.anchor { - case .index: - let anchorIndex = binaryIndexOrLower(sample.entries, sample.anchor) - loop: for i in max(0, anchorIndex) ..< sample.entries.count { - let message = sample.entries[i].message - if !message.media.isEmpty, let peer = message.peers[message.id.peerId] { - for media in message.media { - closestLaterMedia.append(HolesViewMedia(media: media, peer: peer, authorIsContact: sample.entries[i].attributes.authorIsContact, index: message.index)) - } - } - if closestLaterMedia.count >= 3 { - break loop - } + case .loading: + break + case let .loaded(sample): + switch sample.anchor { + case .index: + let anchorIndex = binaryIndexOrLower(sample.entries, sample.anchor) + loop: for i in max(0, anchorIndex) ..< sample.entries.count { + let message = sample.entries[i].message + if !message.media.isEmpty, let peer = message.peers[message.id.peerId] { + for media in message.media { + closestLaterMedia.append(HolesViewMedia(media: media, peer: peer, authorIsContact: sample.entries[i].attributes.authorIsContact, index: message.index)) } - case .lowerBound, .upperBound: - break + } + if closestLaterMedia.count >= 3 { + break loop + } } + case .lowerBound, .upperBound: + break + } } if self.closestHole != closestHole || self.closestLaterMedia != closestLaterMedia { @@ -105,19 +107,25 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView { } var anchor: HistoryViewInputAnchor = self.anchor if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil { + var anchor: HistoryViewInputAnchor = .upperBound if let combinedState = postbox.readStateTable.getCombinedState(peerId), let state = combinedState.states.first, state.1.count != 0 { switch state.1 { - case let .idBased(maxIncomingReadId, _, _, _, _): - anchor = .message(MessageId(peerId: peerId, namespace: state.0, id: maxIncomingReadId)) - case let .indexBased(maxIncomingReadIndex, _, _, _): - anchor = .index(maxIncomingReadIndex) + case let .idBased(maxIncomingReadId, _, _, _, _): + anchor = .message(MessageId(peerId: peerId, namespace: state.0, id: maxIncomingReadId)) + case let .indexBased(maxIncomingReadIndex, _, _, _): + anchor = .index(maxIncomingReadIndex) } } } if self.anchor != anchor { self.anchor = anchor - self.wrappedView = MutableMessageHistoryView(postbox: postbox, orderStatistics: [], peerIds: .single(peerId), anchor: self.anchor, combinedReadStates: nil, transientReadStates: nil, tag: nil, namespaces: .all, count: self.count, topTaggedMessages: [:], additionalDatas: [], getMessageCountInRange: { _, _ in return 0}) + let peerIds: MessageHistoryViewPeerIds + switch self.location { + case let .peer(id): + peerIds = postbox.peerIdsForLocation(.peer(id), tagMask: nil) + } + self.wrappedView = MutableMessageHistoryView(postbox: postbox, orderStatistics: [], peerIds: peerIds, anchor: self.anchor, combinedReadStates: nil, transientReadStates: nil, tag: nil, namespaces: .all, count: self.count, topTaggedMessages: [:], additionalDatas: [], getMessageCountInRange: { _, _ in return 0}) return self.updateFromView() } else if self.wrappedView.replay(postbox: postbox, transaction: transaction) { return self.updateFromView() diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index b185d8a599..957668a110 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -2231,7 +2231,7 @@ public final class Postbox { } } - private func peerIdsForLocation(_ chatLocation: ChatLocation, tagMask: MessageTags?) -> MessageHistoryViewPeerIds { + func peerIdsForLocation(_ chatLocation: ChatLocation, tagMask: MessageTags?) -> MessageHistoryViewPeerIds { var peerIds: MessageHistoryViewPeerIds switch chatLocation { case let .peer(peerId): diff --git a/submodules/Postbox/Sources/ViewTracker.swift b/submodules/Postbox/Sources/ViewTracker.swift index bd232da91f..aa85e15d62 100644 --- a/submodules/Postbox/Sources/ViewTracker.swift +++ b/submodules/Postbox/Sources/ViewTracker.swift @@ -458,14 +458,14 @@ final class ViewTracker { private func updateTrackedHoles() { var firstHolesAndTags = Set() for (view, _) in self.messageHistoryViews.copyItems() { - if let (hole, direction) = view.firstHole() { + if let (hole, direction, count) = view.firstHole() { let space: MessageHistoryHoleSpace if let tag = view.tag { space = .tag(tag) } else { space = .everywhere } - firstHolesAndTags.insert(MessageHistoryHolesViewEntry(hole: hole, direction: direction, space: space)) + firstHolesAndTags.insert(MessageHistoryHolesViewEntry(hole: hole, direction: direction, space: space, count: count)) } } diff --git a/submodules/TelegramCore/Sources/Holes.swift b/submodules/TelegramCore/Sources/Holes.swift index 711946cc3d..404272a3ab 100644 --- a/submodules/TelegramCore/Sources/Holes.swift +++ b/submodules/TelegramCore/Sources/Holes.swift @@ -121,7 +121,7 @@ func withResolvedAssociatedMessages(postbox: Postbox, source: FetchMessageHistor |> switchToLatest } -func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryHoleSource, postbox: Postbox, peerId: PeerId, namespace: MessageId.Namespace, direction: MessageHistoryViewRelativeHoleDirection, space: MessageHistoryHoleSpace, limit: Int = 100) -> Signal { +func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryHoleSource, postbox: Postbox, peerId: PeerId, namespace: MessageId.Namespace, direction: MessageHistoryViewRelativeHoleDirection, space: MessageHistoryHoleSpace, count: Int) -> Signal { return postbox.stateView() |> mapToSignal { view -> Signal in if let state = view.state as? AuthorizedAccountState { @@ -136,8 +136,8 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH |> take(1) |> mapToSignal { peer in if let inputPeer = forceApiInputPeer(peer) { - print("fetchMessageHistoryHole for \(peer.debugDisplayTitle) \(direction) space \(space)") - Logger.shared.log("fetchMessageHistoryHole", "fetch for \(peer.debugDisplayTitle) \(direction) space \(space)") + print("fetchMessageHistoryHole for \(peer.id) \(peer.debugDisplayTitle) \(direction) space \(space)") + Logger.shared.log("fetchMessageHistoryHole", "fetch for \(peer.id) \(peer.debugDisplayTitle) \(direction) space \(space)") let request: Signal var implicitelyFillHole = false let minMaxRange: ClosedRange @@ -146,7 +146,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH case .everywhere: let offsetId: Int32 let addOffset: Int32 - let selectedLimit = limit + let selectedLimit = count let maxId: Int32 let minId: Int32 @@ -195,7 +195,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH if tag == .unseenPersonalMessage { let offsetId: Int32 let addOffset: Int32 - let selectedLimit = limit + let selectedLimit = count let maxId: Int32 let minId: Int32 @@ -241,7 +241,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH request = source.request(Api.functions.messages.getUnreadMentions(peer: inputPeer, offsetId: offsetId, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId)) } else if tag == .liveLocation { - let selectedLimit = limit + let selectedLimit = count switch direction { case .aroundId, .range: @@ -252,7 +252,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH } else if let filter = messageFilterForTagMask(tag) { let offsetId: Int32 let addOffset: Int32 - let selectedLimit = limit + let selectedLimit = count let maxId: Int32 let minId: Int32 @@ -391,7 +391,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH }) updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences) - print("fetchMessageHistoryHole for \(peer.debugDisplayTitle) space \(space) done") + print("fetchMessageHistoryHole for \(peer.id) \(peer.debugDisplayTitle) space \(space) done") return }) diff --git a/submodules/TelegramCore/Sources/ManagedMessageHistoryHoles.swift b/submodules/TelegramCore/Sources/ManagedMessageHistoryHoles.swift index aa18476599..625fb1d7a7 100644 --- a/submodules/TelegramCore/Sources/ManagedMessageHistoryHoles.swift +++ b/submodules/TelegramCore/Sources/ManagedMessageHistoryHoles.swift @@ -49,8 +49,8 @@ func managedMessageHistoryHoles(accountPeerId: PeerId, network: Network, postbox for (entry, disposable) in added { switch entry.hole { - case let .peer(hole): - disposable.set(fetchMessageHistoryHole(accountPeerId: accountPeerId, source: .network(network), postbox: postbox, peerId: hole.peerId, namespace: hole.namespace, direction: entry.direction, space: entry.space).start()) + case let .peer(hole): + disposable.set(fetchMessageHistoryHole(accountPeerId: accountPeerId, source: .network(network), postbox: postbox, peerId: hole.peerId, namespace: hole.namespace, direction: entry.direction, space: entry.space, count: entry.count).start()) } } }) diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index f691a92bc1..a42cc8a7d7 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -14,7 +14,7 @@ import TemporaryCachedPeerDataManager import ChatListSearchItemNode import Emoji -private let historyMessageCount: Int = 100 +private let historyMessageCount: Int = 90 public enum ChatHistoryListMode: Equatable { case bubbles diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryViewForLocation.swift index e2e0b3f3e5..e74f25cafe 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryViewForLocation.swift @@ -206,7 +206,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, account: A let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > index ? .Down : .Up let chatScrollPosition = ChatHistoryViewScrollPosition.index(index: index, position: scrollPosition, directionHint: directionHint, animated: animated) var first = true - return account.viewTracker.aroundMessageHistoryViewForLocation(chatLocation, index: index, anchorIndex: anchorIndex, count: 100, fixedCombinedReadStates: fixedCombinedReadStates, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) + return account.viewTracker.aroundMessageHistoryViewForLocation(chatLocation, index: index, anchorIndex: anchorIndex, count: 128, fixedCombinedReadStates: fixedCombinedReadStates, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) |> map { view, updateType, initialData -> ChatHistoryViewUpdate in let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation)