mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-03 13:13:55 +00:00
no message
This commit is contained in:
parent
872cfb102c
commit
d93a30380e
@ -7,12 +7,12 @@
|
||||
<key>TelegramCore.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>4</integer>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>TelegramCoreMac.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>6</integer>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
||||
@ -44,7 +44,7 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
|
||||
func updateView(id: Int32, view: MessageHistoryView?) {
|
||||
assert(self.queue.isCurrent())
|
||||
if let view = view {
|
||||
if let view = view, view.tagMask == nil {
|
||||
var channelState: ChannelState?
|
||||
for entry in view.additionalData {
|
||||
if case let .peerChatState(_, chatState) = entry {
|
||||
@ -56,8 +56,20 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
}
|
||||
|
||||
if let invalidatedPts = channelState?.invalidatedPts {
|
||||
var invalidatedMessageIds: [MessageId] = []
|
||||
var minValidatedPts: Int32?
|
||||
var rangesToInvalidate: [[MessageId]] = []
|
||||
let addToRange: (MessageId, inout [[MessageId]]) -> Void = { id, ranges in
|
||||
if ranges.isEmpty {
|
||||
ranges = [[id]]
|
||||
} else {
|
||||
ranges[rangesToInvalidate.count - 1].append(id)
|
||||
}
|
||||
}
|
||||
|
||||
let addRangeBreak: (inout [[MessageId]]) -> Void = { ranges in
|
||||
if ranges.last?.count != 0 {
|
||||
ranges.append([])
|
||||
}
|
||||
}
|
||||
|
||||
for entry in view.entries {
|
||||
switch entry {
|
||||
@ -70,23 +82,35 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
break inner
|
||||
}
|
||||
}
|
||||
var requiresValidation = false
|
||||
if let messagePts = messagePts {
|
||||
if messagePts < invalidatedPts {
|
||||
if minValidatedPts == nil || minValidatedPts! > messagePts {
|
||||
minValidatedPts = messagePts
|
||||
}
|
||||
invalidatedMessageIds.append(message.id)
|
||||
requiresValidation = true
|
||||
}
|
||||
} else {
|
||||
invalidatedMessageIds.append(message.id)
|
||||
requiresValidation = true
|
||||
}
|
||||
|
||||
if requiresValidation {
|
||||
addToRange(message.id, &rangesToInvalidate)
|
||||
} else {
|
||||
addRangeBreak(&rangesToInvalidate)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
case let .HoleEntry(hole, _):
|
||||
if hole.maxIndex.id.namespace == Namespaces.Message.Cloud {
|
||||
addRangeBreak(&rangesToInvalidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !invalidatedMessageIds.isEmpty {
|
||||
if !rangesToInvalidate.isEmpty && rangesToInvalidate[rangesToInvalidate.count - 1].isEmpty {
|
||||
rangesToInvalidate.removeLast()
|
||||
}
|
||||
|
||||
var invalidatedMessageIds = Set<MessageId>()
|
||||
|
||||
if !rangesToInvalidate.isEmpty {
|
||||
let context: ChannelStateValidationContext
|
||||
if let current = self.contexts[id] {
|
||||
context = current
|
||||
@ -94,7 +118,46 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
context = ChannelStateValidationContext()
|
||||
self.contexts[id] = context
|
||||
}
|
||||
var messageIdsForBatch: [MessageId] = []
|
||||
|
||||
var addedRanges: [[MessageId]] = []
|
||||
for messages in rangesToInvalidate {
|
||||
for id in messages {
|
||||
if context.batchReferences[id] != nil {
|
||||
addRangeBreak(&addedRanges)
|
||||
} else {
|
||||
addToRange(id, &addedRanges)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !addedRanges.isEmpty && addedRanges[rangesToInvalidate.count - 1].isEmpty {
|
||||
addedRanges.removeLast()
|
||||
}
|
||||
|
||||
for messages in addedRanges {
|
||||
let disposable = MetaDisposable()
|
||||
let batch = ChannelStateValidationBatch(disposable: disposable, invalidatedPts: invalidatedPts)
|
||||
for messageId in messages {
|
||||
context.batchReferences[messageId] = batch
|
||||
}
|
||||
|
||||
disposable.set((validateBatch(postbox: self.postbox, network: self.network, messageIds: messages)
|
||||
|> deliverOn(self.queue)).start(completed: { [weak self, weak batch] in
|
||||
if let strongSelf = self, let context = strongSelf.contexts[id], let batch = batch {
|
||||
var completedMessageIds: [MessageId] = []
|
||||
for (messageId, messageBatch) in context.batchReferences {
|
||||
if messageBatch === batch {
|
||||
completedMessageIds.append(messageId)
|
||||
}
|
||||
}
|
||||
for messageId in completedMessageIds {
|
||||
context.batchReferences.removeValue(forKey: messageId)
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
/*var messageIdsForBatch: [MessageId] = []
|
||||
for messageId in invalidatedMessageIds {
|
||||
if let batch = context.batchReferences[messageId] {
|
||||
if batch.invalidatedPts < invalidatedPts {
|
||||
@ -126,15 +189,14 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if let context = self.contexts[id] {
|
||||
let messageIds = Set(invalidatedMessageIds)
|
||||
var removeIds: [MessageId] = []
|
||||
|
||||
for batchMessageId in context.batchReferences.keys {
|
||||
if !messageIds.contains(batchMessageId) {
|
||||
if !invalidatedMessageIds.contains(batchMessageId) {
|
||||
removeIds.append(batchMessageId)
|
||||
}
|
||||
}
|
||||
@ -150,136 +212,37 @@ final class HistoryViewChannelStateValidationContexts {
|
||||
}
|
||||
}
|
||||
|
||||
private func validateBatch(postbox: Postbox, network: Network, messageIds: [MessageId], minValidatedPts: Int32?) -> Signal<Void, NoError> {
|
||||
private func hashForMessages(_ messages: [Message]) -> Int32 {
|
||||
var acc: UInt32 = 0
|
||||
|
||||
for message in messages {
|
||||
acc = (acc &* 20261) &+ message.id.id
|
||||
var timestamp = message.timestamp
|
||||
inner: for attribute in message.attributes {
|
||||
if let attribute = attribute as? EditedMessageAttribute {
|
||||
timestamp = attribute.date
|
||||
break inner
|
||||
}
|
||||
}
|
||||
acc = (acc &* 20261) &+ timestamp
|
||||
}
|
||||
return Int32(bitPattern: acc & UInt32(0x7FFFFFFF))
|
||||
}
|
||||
|
||||
private func validateBatch(postbox: Postbox, network: Network, messageIds: [MessageId]) -> Signal<Void, NoError> {
|
||||
guard let peerId = messageIds.first?.peerId else {
|
||||
return .never()
|
||||
}
|
||||
return postbox.modify { modifier -> Signal<Void, NoError> in
|
||||
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
||||
var ranges: [Api.MessageRange] = []
|
||||
var currentRange: (Int32, Int32)?
|
||||
for id in messageIds.sorted() {
|
||||
if let (minId, maxId) = currentRange {
|
||||
if maxId == id.id - 1 {
|
||||
currentRange = (minId, id.id)
|
||||
} else {
|
||||
ranges.append(Api.MessageRange.messageRange(minId: minId - 1, maxId: maxId + 1))
|
||||
currentRange = (id.id, id.id)
|
||||
}
|
||||
} else {
|
||||
currentRange = (id.id, id.id)
|
||||
if let peer = modifier.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||
var messages: [Message] = []
|
||||
for messageId in messageIds {
|
||||
if let message = modifier.getMessage(messageId) {
|
||||
messages.append(message)
|
||||
}
|
||||
}
|
||||
if let (minId, maxId) = currentRange {
|
||||
ranges.append(Api.MessageRange.messageRange(minId: minId, maxId: maxId))
|
||||
}
|
||||
return network.request(Api.functions.updates.getChannelDifference(flags: 0, channel: inputChannel, filter: .channelMessagesFilter(flags: 1 << 1, ranges: ranges), pts: minValidatedPts ?? 1, limit: 100))
|
||||
|> `catch` { _ -> Signal<Api.updates.ChannelDifference, NoError> in
|
||||
return .never()
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
return postbox.modify { modifier -> Void in
|
||||
let finalPts: Int32
|
||||
var deletedMessageIds: [MessageId] = []
|
||||
var updatedMessages: [MessageId: StoreMessage] = [:]
|
||||
|
||||
var apiChats: [Api.Chat] = []
|
||||
var apiUsers: [Api.User] = []
|
||||
|
||||
switch result {
|
||||
case let .channelDifference(_, pts, _, newMessages, otherUpdates, chats, users):
|
||||
finalPts = pts
|
||||
apiChats = chats
|
||||
apiUsers = users
|
||||
|
||||
for message in newMessages {
|
||||
if let message = StoreMessage(apiMessage: message), case let .Id(id) = message.id {
|
||||
updatedMessages[id] = message
|
||||
}
|
||||
}
|
||||
for update in otherUpdates {
|
||||
switch update {
|
||||
case let .updateDeleteChannelMessages(_, messages, _, _):
|
||||
for messageId in messages {
|
||||
deletedMessageIds.append(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: messageId))
|
||||
}
|
||||
case let .updateNewChannelMessage(message, _, _):
|
||||
if let message = StoreMessage(apiMessage: message), case let .Id(id) = message.id {
|
||||
updatedMessages[id] = message
|
||||
}
|
||||
case let .updateEditChannelMessage(message, _, _):
|
||||
if let message = StoreMessage(apiMessage: message), case let .Id(id) = message.id {
|
||||
updatedMessages[id] = message
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
case let .channelDifferenceEmpty(_, pts, _):
|
||||
finalPts = pts
|
||||
case let .channelDifferenceTooLong(_, pts, _, _, _, _, _, _, _, _, _):
|
||||
finalPts = pts
|
||||
}
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
for chat in apiChats {
|
||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||
peers.append(groupOrChannel)
|
||||
}
|
||||
}
|
||||
for user in apiUsers {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
peers.append(telegramUser)
|
||||
if let presence = TelegramUserPresence(apiUser: user) {
|
||||
peerPresences[telegramUser.id] = presence
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(modifier: modifier, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
modifier.updatePeerPresences(peerPresences)
|
||||
|
||||
if !deletedMessageIds.isEmpty {
|
||||
modifier.deleteMessages(deletedMessageIds)
|
||||
}
|
||||
|
||||
for (messageId, message) in updatedMessages {
|
||||
modifier.updateMessage(messageId, update: { _ in
|
||||
var attributes = message.attributes
|
||||
for j in 0 ..< attributes.count {
|
||||
if let _ = attributes[j] as? ChannelMessageStateVersionAttribute {
|
||||
attributes.remove(at: j)
|
||||
break
|
||||
}
|
||||
}
|
||||
attributes.append(ChannelMessageStateVersionAttribute(pts: finalPts))
|
||||
return .update(StoreMessage(id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, authorId: message.authorId, text: message.text, attributes: attributes, media: message.media))
|
||||
})
|
||||
}
|
||||
|
||||
for messageId in messageIds {
|
||||
if updatedMessages[messageId] == nil {
|
||||
modifier.updateMessage(messageId, update: { currentMessage in
|
||||
var storeForwardInfo: StoreMessageForwardInfo?
|
||||
if let forwardInfo = currentMessage.forwardInfo {
|
||||
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature)
|
||||
}
|
||||
var attributes = currentMessage.attributes
|
||||
for j in 0 ..< attributes.count {
|
||||
if let _ = attributes[j] as? ChannelMessageStateVersionAttribute {
|
||||
attributes.remove(at: j)
|
||||
break
|
||||
}
|
||||
}
|
||||
attributes.append(ChannelMessageStateVersionAttribute(pts: finalPts))
|
||||
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let hash = hashForMessages(messages)
|
||||
return network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: messageIds[messageIds.count - 1].id, offsetDate: 0, addOffset: 0, limit: 100, maxId: messageIds[messageIds.cout - 1].id, minId: messageIds[0].id))
|
||||
} else {
|
||||
return .never()
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user