mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-13 14:59:23 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
987cbeae08
@ -272,6 +272,8 @@ final class MutableMessageHistoryView {
|
|||||||
|
|
||||||
fileprivate(set) var sampledState: HistoryViewSample
|
fileprivate(set) var sampledState: HistoryViewSample
|
||||||
|
|
||||||
|
fileprivate var isAddedToChatList: Bool
|
||||||
|
|
||||||
init(postbox: Postbox, orderStatistics: MessageHistoryViewOrderStatistics, clipHoles: Bool, peerIds: MessageHistoryViewPeerIds, anchor inputAnchor: HistoryViewInputAnchor, combinedReadStates: MessageHistoryViewReadState?, transientReadStates: MessageHistoryViewReadState?, tag: MessageTags?, namespaces: MessageIdNamespaces, count: Int, topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?], additionalDatas: [AdditionalMessageHistoryViewDataEntry], getMessageCountInRange: (MessageIndex, MessageIndex) -> Int32) {
|
init(postbox: Postbox, orderStatistics: MessageHistoryViewOrderStatistics, clipHoles: Bool, peerIds: MessageHistoryViewPeerIds, anchor inputAnchor: HistoryViewInputAnchor, combinedReadStates: MessageHistoryViewReadState?, transientReadStates: MessageHistoryViewReadState?, tag: MessageTags?, namespaces: MessageIdNamespaces, count: Int, topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?], additionalDatas: [AdditionalMessageHistoryViewDataEntry], getMessageCountInRange: (MessageIndex, MessageIndex) -> Int32) {
|
||||||
self.anchor = inputAnchor
|
self.anchor = inputAnchor
|
||||||
|
|
||||||
@ -286,6 +288,15 @@ final class MutableMessageHistoryView {
|
|||||||
self.topTaggedMessages = topTaggedMessages
|
self.topTaggedMessages = topTaggedMessages
|
||||||
self.additionalDatas = additionalDatas
|
self.additionalDatas = additionalDatas
|
||||||
|
|
||||||
|
let mainPeerId: PeerId
|
||||||
|
switch peerIds {
|
||||||
|
case let .associated(peerId, _):
|
||||||
|
mainPeerId = peerId
|
||||||
|
case let .single(peerId):
|
||||||
|
mainPeerId = peerId
|
||||||
|
}
|
||||||
|
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: mainPeerId) != nil
|
||||||
|
|
||||||
self.state = HistoryViewState(postbox: postbox, inputAnchor: inputAnchor, tag: tag, namespaces: namespaces, statistics: self.orderStatistics, halfLimit: count + 1, locations: peerIds)
|
self.state = HistoryViewState(postbox: postbox, inputAnchor: inputAnchor, tag: tag, namespaces: namespaces, statistics: self.orderStatistics, halfLimit: count + 1, locations: peerIds)
|
||||||
if case let .loading(loadingState) = self.state {
|
if case let .loading(loadingState) = self.state {
|
||||||
let sampledState = loadingState.checkAndSample(postbox: postbox)
|
let sampledState = loadingState.checkAndSample(postbox: postbox)
|
||||||
@ -351,6 +362,17 @@ final class MutableMessageHistoryView {
|
|||||||
var operations: [[MessageHistoryOperation]] = []
|
var operations: [[MessageHistoryOperation]] = []
|
||||||
var peerIdsSet = Set<PeerId>()
|
var peerIdsSet = Set<PeerId>()
|
||||||
|
|
||||||
|
if !transaction.chatListOperations.isEmpty {
|
||||||
|
let mainPeerId: PeerId
|
||||||
|
switch peerIds {
|
||||||
|
case let .associated(peerId, _):
|
||||||
|
mainPeerId = peerId
|
||||||
|
case let .single(peerId):
|
||||||
|
mainPeerId = peerId
|
||||||
|
}
|
||||||
|
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: mainPeerId) != nil
|
||||||
|
}
|
||||||
|
|
||||||
switch self.peerIds {
|
switch self.peerIds {
|
||||||
case let .single(peerId):
|
case let .single(peerId):
|
||||||
peerIdsSet.insert(peerId)
|
peerIdsSet.insert(peerId)
|
||||||
@ -718,10 +740,12 @@ public final class MessageHistoryView {
|
|||||||
public let topTaggedMessages: [Message]
|
public let topTaggedMessages: [Message]
|
||||||
public let additionalData: [AdditionalMessageHistoryViewDataEntry]
|
public let additionalData: [AdditionalMessageHistoryViewDataEntry]
|
||||||
public let isLoading: Bool
|
public let isLoading: Bool
|
||||||
|
public let isAddedToChatList: Bool
|
||||||
|
|
||||||
init(_ mutableView: MutableMessageHistoryView) {
|
init(_ mutableView: MutableMessageHistoryView) {
|
||||||
self.tagMask = mutableView.tag
|
self.tagMask = mutableView.tag
|
||||||
self.namespaces = mutableView.namespaces
|
self.namespaces = mutableView.namespaces
|
||||||
|
self.isAddedToChatList = mutableView.isAddedToChatList
|
||||||
var entries: [MessageHistoryEntry]
|
var entries: [MessageHistoryEntry]
|
||||||
switch mutableView.sampledState {
|
switch mutableView.sampledState {
|
||||||
case .loading:
|
case .loading:
|
||||||
|
@ -945,6 +945,10 @@ public final class Transaction {
|
|||||||
self.postbox?.scanMessages(peerId: peerId, namespace: namespace, tag: tag, f)
|
self.postbox?.scanMessages(peerId: peerId, namespace: namespace, tag: tag, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func scanMessageAttributes(peerId: PeerId, namespace: MessageId.Namespace, _ f: (MessageId, [MessageAttribute]) -> Bool) {
|
||||||
|
self.postbox?.scanMessageAttributes(peerId: peerId, namespace: namespace, f)
|
||||||
|
}
|
||||||
|
|
||||||
public func invalidateMessageHistoryTagsSummary(peerId: PeerId, namespace: MessageId.Namespace, tagMask: MessageTags) {
|
public func invalidateMessageHistoryTagsSummary(peerId: PeerId, namespace: MessageId.Namespace, tagMask: MessageTags) {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
self.postbox?.invalidateMessageHistoryTagsSummary(peerId: peerId, namespace: namespace, tagMask: tagMask)
|
self.postbox?.invalidateMessageHistoryTagsSummary(peerId: peerId, namespace: namespace, tagMask: tagMask)
|
||||||
@ -1043,7 +1047,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
|||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//debugSaveState(basePath: basePath, name: "previous1")
|
//debugSaveState(basePath: basePath, name: "previous1")
|
||||||
//debugRestoreState(basePath: basePath, name: "previous1")
|
debugRestoreState(basePath: basePath, name: "previous1")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
let startTime = CFAbsoluteTimeGetCurrent()
|
||||||
@ -3170,6 +3174,24 @@ public final class Postbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func scanMessageAttributes(peerId: PeerId, namespace: MessageId.Namespace, _ f: (MessageId, [MessageAttribute]) -> Bool) {
|
||||||
|
var index = MessageIndex.upperBound(peerId: peerId, namespace: namespace)
|
||||||
|
while true {
|
||||||
|
let messages = self.messageHistoryTable.fetch(peerId: peerId, namespace: namespace, tag: nil, from: index, includeFrom: false, to: MessageIndex.lowerBound(peerId: peerId, namespace: namespace), limit: 32)
|
||||||
|
for message in messages {
|
||||||
|
let attributes = MessageHistoryTable.renderMessageAttributes(message)
|
||||||
|
if !f(message.id, attributes) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let last = messages.last {
|
||||||
|
index = last.index
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileprivate func invalidateMessageHistoryTagsSummary(peerId: PeerId, namespace: MessageId.Namespace, tagMask: MessageTags) {
|
fileprivate func invalidateMessageHistoryTagsSummary(peerId: PeerId, namespace: MessageId.Namespace, tagMask: MessageTags) {
|
||||||
self.invalidatedMessageHistoryTagsSummaryTable.insert(InvalidatedMessageHistoryTagsSummaryKey(peerId: peerId, namespace: namespace, tagMask: tagMask), operations: &self.currentInvalidateMessageTagSummaries)
|
self.invalidatedMessageHistoryTagsSummaryTable.insert(InvalidatedMessageHistoryTagsSummaryKey(peerId: peerId, namespace: namespace, tagMask: tagMask), operations: &self.currentInvalidateMessageTagSummaries)
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,22 @@ enum AccountStateMutationOperation {
|
|||||||
case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?)
|
case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HoleFromPreviousState {
|
||||||
|
var validateChannelPts: Int32?
|
||||||
|
|
||||||
|
func mergedWith(_ other: HoleFromPreviousState) -> HoleFromPreviousState {
|
||||||
|
var result = self
|
||||||
|
if let pts = self.validateChannelPts, let otherPts = other.validateChannelPts {
|
||||||
|
result.validateChannelPts = max(pts, otherPts)
|
||||||
|
} else if let pts = self.validateChannelPts {
|
||||||
|
result.validateChannelPts = pts
|
||||||
|
} else if let otherPts = other.validateChannelPts {
|
||||||
|
result.validateChannelPts = otherPts
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct AccountMutableState {
|
struct AccountMutableState {
|
||||||
let initialState: AccountInitialState
|
let initialState: AccountInitialState
|
||||||
let branchOperationIndex: Int
|
let branchOperationIndex: Int
|
||||||
@ -122,7 +138,7 @@ struct AccountMutableState {
|
|||||||
var referencedMessageIds: Set<MessageId>
|
var referencedMessageIds: Set<MessageId>
|
||||||
var storedMessages: Set<MessageId>
|
var storedMessages: Set<MessageId>
|
||||||
var readInboxMaxIds: [PeerId: MessageId]
|
var readInboxMaxIds: [PeerId: MessageId]
|
||||||
var namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>]
|
var namespacesWithHolesFromPreviousState: [PeerId: [MessageId.Namespace: HoleFromPreviousState]]
|
||||||
var updatedOutgoingUniqueMessageIds: [Int64: Int32]
|
var updatedOutgoingUniqueMessageIds: [Int64: Int32]
|
||||||
|
|
||||||
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
|
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
|
||||||
@ -154,7 +170,7 @@ struct AccountMutableState {
|
|||||||
self.updatedOutgoingUniqueMessageIds = [:]
|
self.updatedOutgoingUniqueMessageIds = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], channelStates: [PeerId: AccountStateChannelState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], updatedOutgoingUniqueMessageIds: [Int64: Int32], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
|
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], channelStates: [PeerId: AccountStateChannelState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: [MessageId.Namespace: HoleFromPreviousState]], updatedOutgoingUniqueMessageIds: [Int64: Int32], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
|
||||||
self.initialState = initialState
|
self.initialState = initialState
|
||||||
self.operations = operations
|
self.operations = operations
|
||||||
self.state = state
|
self.state = state
|
||||||
@ -187,10 +203,14 @@ struct AccountMutableState {
|
|||||||
self.externallyUpdatedPeerId.formUnion(other.externallyUpdatedPeerId)
|
self.externallyUpdatedPeerId.formUnion(other.externallyUpdatedPeerId)
|
||||||
for (peerId, namespaces) in other.namespacesWithHolesFromPreviousState {
|
for (peerId, namespaces) in other.namespacesWithHolesFromPreviousState {
|
||||||
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
|
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
|
||||||
self.namespacesWithHolesFromPreviousState[peerId] = Set()
|
self.namespacesWithHolesFromPreviousState[peerId] = [:]
|
||||||
}
|
}
|
||||||
for namespace in namespaces {
|
for (namespace, namespaceState) in namespaces {
|
||||||
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
|
if self.namespacesWithHolesFromPreviousState[peerId]![namespace] == nil {
|
||||||
|
self.namespacesWithHolesFromPreviousState[peerId]![namespace] = namespaceState
|
||||||
|
} else {
|
||||||
|
self.namespacesWithHolesFromPreviousState[peerId]![namespace] = self.namespacesWithHolesFromPreviousState[peerId]![namespace]!.mergedWith(namespaceState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.updatedOutgoingUniqueMessageIds.merge(other.updatedOutgoingUniqueMessageIds, uniquingKeysWith: { lhs, _ in lhs })
|
self.updatedOutgoingUniqueMessageIds.merge(other.updatedOutgoingUniqueMessageIds, uniquingKeysWith: { lhs, _ in lhs })
|
||||||
@ -296,11 +316,16 @@ struct AccountMutableState {
|
|||||||
self.addOperation(.UpdateGlobalNotificationSettings(subject, notificationSettings))
|
self.addOperation(.UpdateGlobalNotificationSettings(subject, notificationSettings))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func setNeedsHoleFromPreviousState(peerId: PeerId, namespace: MessageId.Namespace) {
|
mutating func setNeedsHoleFromPreviousState(peerId: PeerId, namespace: MessageId.Namespace, validateChannelPts: Int32?) {
|
||||||
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
|
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
|
||||||
self.namespacesWithHolesFromPreviousState[peerId] = Set()
|
self.namespacesWithHolesFromPreviousState[peerId] = [:]
|
||||||
|
}
|
||||||
|
let namespaceState = HoleFromPreviousState(validateChannelPts: validateChannelPts)
|
||||||
|
if self.namespacesWithHolesFromPreviousState[peerId]![namespace] == nil {
|
||||||
|
self.namespacesWithHolesFromPreviousState[peerId]![namespace] = namespaceState
|
||||||
|
} else {
|
||||||
|
self.namespacesWithHolesFromPreviousState[peerId]![namespace] = self.namespacesWithHolesFromPreviousState[peerId]![namespace]!.mergedWith(namespaceState)
|
||||||
}
|
}
|
||||||
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func mergeChats(_ chats: [Api.Chat]) {
|
mutating func mergeChats(_ chats: [Api.Chat]) {
|
||||||
|
@ -1510,7 +1510,7 @@ private func resolveMissingPeerChatInfos(network: Network, state: AccountMutable
|
|||||||
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, notifySettings, pts, _, folderId):
|
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, notifySettings, pts, _, folderId):
|
||||||
let peerId = peer.peerId
|
let peerId = peer.peerId
|
||||||
|
|
||||||
updatedState.setNeedsHoleFromPreviousState(peerId: peerId, namespace: Namespaces.Message.Cloud)
|
updatedState.setNeedsHoleFromPreviousState(peerId: peerId, namespace: Namespaces.Message.Cloud, validateChannelPts: pts)
|
||||||
|
|
||||||
if topMessage != 0 {
|
if topMessage != 0 {
|
||||||
topMessageIds.insert(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: topMessage))
|
topMessageIds.insert(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: topMessage))
|
||||||
@ -1590,7 +1590,7 @@ private func resolveMissingPeerChatInfos(network: Network, state: AccountMutable
|
|||||||
}
|
}
|
||||||
|
|
||||||
func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
let signal: Signal<Void, NoError> = postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
if let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) {
|
if let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) {
|
||||||
var channelStates: [PeerId: AccountStateChannelState] = [:]
|
var channelStates: [PeerId: AccountStateChannelState] = [:]
|
||||||
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
@ -1635,6 +1635,9 @@ func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stat
|
|||||||
}
|
}
|
||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
|> restart
|
|> restart
|
||||||
|
|
||||||
|
return signal
|
||||||
|
|> delay(5.0, queue: .concurrentDefaultQueue())
|
||||||
}
|
}
|
||||||
|
|
||||||
private func resetChannels(network: Network, peers: [Peer], state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
private func resetChannels(network: Network, peers: [Peer], state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
||||||
@ -1751,7 +1754,11 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
|
|||||||
|
|
||||||
for message in storeMessages {
|
for message in storeMessages {
|
||||||
if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
|
if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
|
||||||
updatedState.setNeedsHoleFromPreviousState(peerId: id.peerId, namespace: id.namespace)
|
var channelPts: Int32?
|
||||||
|
if let state = channelStates[id.peerId] {
|
||||||
|
channelPts = state.pts
|
||||||
|
}
|
||||||
|
updatedState.setNeedsHoleFromPreviousState(peerId: id.peerId, namespace: id.namespace, validateChannelPts: channelPts)
|
||||||
channelSynchronizedUntilMessage[id.peerId] = id.id
|
channelSynchronizedUntilMessage[id.peerId] = id.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1841,7 +1848,11 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
updatedState.mergeUsers(users)
|
updatedState.mergeUsers(users)
|
||||||
|
|
||||||
for apiMessage in newMessages {
|
for apiMessage in newMessages {
|
||||||
if let message = StoreMessage(apiMessage: apiMessage) {
|
if var message = StoreMessage(apiMessage: apiMessage) {
|
||||||
|
var attributes = message.attributes
|
||||||
|
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
||||||
|
message = message.withUpdatedAttributes(attributes)
|
||||||
|
|
||||||
if let preCachedResources = apiMessage.preCachedResources {
|
if let preCachedResources = apiMessage.preCachedResources {
|
||||||
for (resource, data) in preCachedResources {
|
for (resource, data) in preCachedResources {
|
||||||
updatedState.addPreCachedResource(resource, data: data)
|
updatedState.addPreCachedResource(resource, data: data)
|
||||||
@ -1941,10 +1952,14 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
updatedState.mergeChats(chats)
|
updatedState.mergeChats(chats)
|
||||||
updatedState.mergeUsers(users)
|
updatedState.mergeUsers(users)
|
||||||
|
|
||||||
updatedState.setNeedsHoleFromPreviousState(peerId: peer.peerId, namespace: Namespaces.Message.Cloud)
|
updatedState.setNeedsHoleFromPreviousState(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, validateChannelPts: pts)
|
||||||
|
|
||||||
for apiMessage in messages {
|
for apiMessage in messages {
|
||||||
if let message = StoreMessage(apiMessage: apiMessage) {
|
if var message = StoreMessage(apiMessage: apiMessage) {
|
||||||
|
var attributes = message.attributes
|
||||||
|
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
||||||
|
message = message.withUpdatedAttributes(attributes)
|
||||||
|
|
||||||
if let preCachedResources = apiMessage.preCachedResources {
|
if let preCachedResources = apiMessage.preCachedResources {
|
||||||
for (resource, data) in preCachedResources {
|
for (resource, data) in preCachedResources {
|
||||||
updatedState.addPreCachedResource(resource, data: data)
|
updatedState.addPreCachedResource(resource, data: data)
|
||||||
@ -2175,9 +2190,14 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
var syncChatListFilters = false
|
var syncChatListFilters = false
|
||||||
|
|
||||||
var holesFromPreviousStateMessageIds: [MessageId] = []
|
var holesFromPreviousStateMessageIds: [MessageId] = []
|
||||||
|
var clearHolesFromPreviousStateForChannelMessagesWithPts: [PeerIdAndMessageNamespace: Int32] = [:]
|
||||||
|
|
||||||
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
|
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
|
||||||
for namespace in namespaces {
|
for (namespace, namespaceState) in namespaces {
|
||||||
|
if let pts = namespaceState.validateChannelPts {
|
||||||
|
clearHolesFromPreviousStateForChannelMessagesWithPts[PeerIdAndMessageNamespace(peerId: peerId, namespace: namespace)] = pts
|
||||||
|
}
|
||||||
|
|
||||||
var topId: Int32?
|
var topId: Int32?
|
||||||
if namespace == Namespaces.Message.Cloud, let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
if namespace == Namespaces.Message.Cloud, let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
if let synchronizedUntilMessageId = channelState.synchronizedUntilMessageId {
|
if let synchronizedUntilMessageId = channelState.synchronizedUntilMessageId {
|
||||||
@ -2838,6 +2858,36 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (peerIdAndNamespace, pts) in clearHolesFromPreviousStateForChannelMessagesWithPts {
|
||||||
|
var upperMessageId: Int32?
|
||||||
|
var lowerMessageId: Int32?
|
||||||
|
transaction.scanMessageAttributes(peerId: peerIdAndNamespace.peerId, namespace: peerIdAndNamespace.namespace, { id, attributes in
|
||||||
|
for attribute in attributes {
|
||||||
|
if let attribute = attribute as? ChannelMessageStateVersionAttribute {
|
||||||
|
if attribute.pts >= pts {
|
||||||
|
if upperMessageId == nil {
|
||||||
|
upperMessageId = id.id
|
||||||
|
}
|
||||||
|
if let lowerMessageIdValue = lowerMessageId {
|
||||||
|
lowerMessageId = min(id.id, lowerMessageIdValue)
|
||||||
|
} else {
|
||||||
|
lowerMessageId = id.id
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if let upperMessageId = upperMessageId, let lowerMessageId = lowerMessageId {
|
||||||
|
if upperMessageId != lowerMessageId {
|
||||||
|
transaction.removeHole(peerId: peerIdAndNamespace.peerId, namespace: peerIdAndNamespace.namespace, space: .everywhere, range: lowerMessageId ... upperMessageId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !peerActivityTimestamps.isEmpty {
|
if !peerActivityTimestamps.isEmpty {
|
||||||
updatePeerPresenceLastActivities(transaction: transaction, accountPeerId: accountPeerId, activities: peerActivityTimestamps)
|
updatePeerPresenceLastActivities(transaction: transaction, accountPeerId: accountPeerId, activities: peerActivityTimestamps)
|
||||||
}
|
}
|
||||||
|
@ -1111,13 +1111,13 @@ public final class AccountViewTracker {
|
|||||||
let combinedDisposable = MetaDisposable()
|
let combinedDisposable = MetaDisposable()
|
||||||
self.queue.async {
|
self.queue.async {
|
||||||
var addHole = false
|
var addHole = false
|
||||||
/*if let context = self.channelPollingContexts[peerId] {
|
if let context = self.channelPollingContexts[peerId] {
|
||||||
if context.subscribers.isEmpty {
|
if context.subscribers.isEmpty {
|
||||||
addHole = true
|
addHole = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addHole = true
|
addHole = true
|
||||||
}*/
|
}
|
||||||
if addHole {
|
if addHole {
|
||||||
let _ = self.account?.postbox.transaction({ transaction -> Void in
|
let _ = self.account?.postbox.transaction({ transaction -> Void in
|
||||||
if transaction.getPeerChatListIndex(peerId) == nil {
|
if transaction.getPeerChatListIndex(peerId) == nil {
|
||||||
|
@ -1435,7 +1435,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
loadState = .loading
|
loadState = .loading
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var animateIn = false
|
||||||
if strongSelf.loadState != loadState {
|
if strongSelf.loadState != loadState {
|
||||||
|
if case .loading = strongSelf.loadState {
|
||||||
|
if case .messages = loadState {
|
||||||
|
animateIn = true
|
||||||
|
}
|
||||||
|
}
|
||||||
strongSelf.loadState = loadState
|
strongSelf.loadState = loadState
|
||||||
strongSelf.loadStateUpdated?(loadState, animated)
|
strongSelf.loadStateUpdated?(loadState, animated)
|
||||||
}
|
}
|
||||||
@ -1478,8 +1484,24 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
strongSelf._buttonKeyboardMessage.set(.single(transition.keyboardButtonsMessage))
|
strongSelf._buttonKeyboardMessage.set(.single(transition.keyboardButtonsMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
if transition.animateIn {
|
if transition.animateIn || animateIn {
|
||||||
strongSelf.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
let heightNorm = strongSelf.bounds.height - strongSelf.insets.top
|
||||||
|
strongSelf.forEachVisibleItemNode { itemNode in
|
||||||
|
if let itemNode = itemNode as? ChatMessageItemView {
|
||||||
|
let delayFactor = itemNode.frame.minY / heightNorm
|
||||||
|
let delay = Double(delayFactor * 0.1)
|
||||||
|
|
||||||
|
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay)
|
||||||
|
itemNode.layer.animateScale(from: 0.9, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strongSelf.forEachItemHeaderNode { itemNode in
|
||||||
|
let delayFactor = itemNode.frame.minY / heightNorm
|
||||||
|
let delay = Double(delayFactor * 0.2)
|
||||||
|
|
||||||
|
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay)
|
||||||
|
itemNode.layer.animateScale(from: 0.9, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let scrolledToIndex = transition.scrolledToIndex {
|
if let scrolledToIndex = transition.scrolledToIndex {
|
||||||
|
@ -83,7 +83,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, account: A
|
|||||||
}
|
}
|
||||||
var scrollPosition: ChatHistoryViewScrollPosition?
|
var scrollPosition: ChatHistoryViewScrollPosition?
|
||||||
|
|
||||||
if let maxReadIndex = view.maxReadIndex, tagMask == nil {
|
if let maxReadIndex = view.maxReadIndex, tagMask == nil, view.isAddedToChatList {
|
||||||
let aroundIndex = maxReadIndex
|
let aroundIndex = maxReadIndex
|
||||||
scrollPosition = .unread(index: maxReadIndex)
|
scrollPosition = .unread(index: maxReadIndex)
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, account: A
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let historyScrollState = (initialData?.chatInterfaceState as? ChatInterfaceState)?.historyScrollState, tagMask == nil {
|
} else if view.isAddedToChatList, let historyScrollState = (initialData?.chatInterfaceState as? ChatInterfaceState)?.historyScrollState, tagMask == nil {
|
||||||
scrollPosition = .positionRestoration(index: historyScrollState.messageIndex, relativeOffset: CGFloat(historyScrollState.relativeOffset))
|
scrollPosition = .positionRestoration(index: historyScrollState.messageIndex, relativeOffset: CGFloat(historyScrollState.relativeOffset))
|
||||||
} else {
|
} else {
|
||||||
if view.entries.isEmpty && (view.holeEarlier || view.holeLater) {
|
if view.entries.isEmpty && (view.holeEarlier || view.holeLater) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user