no message

This commit is contained in:
Peter Iakovlev 2018-01-12 17:30:17 +04:00
parent 15be8bb5e6
commit d04264c127
11 changed files with 219 additions and 41 deletions

View File

@ -1157,6 +1157,8 @@ private func resolveAssociatedMessages(account: Account, state: AccountMutableSt
return (messages, chats, users)
case let .channelMessages(_, _, _, messages, chats, users):
return (messages, chats, users)
case .messagesNotModified:
return ([], [], [])
}
} |> `catch` { _ in
return Signal<([Api.Message], [Api.Chat], [Api.User]), NoError>.single(([], [], []))

View File

@ -77,6 +77,10 @@ private func fetchWebpage(account: Account, messageId: MessageId) -> Signal<Void
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
messages = []
chats = []
users = []
}
return account.postbox.modify { modifier -> Void in

View File

@ -108,7 +108,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
case .chat, .chatEmpty, .chatForbidden, .channelForbidden:
return parseTelegramGroupOrChannel(chat: rhs)
case let .channel(flags, _, accessHash, title, username, photo, date, version, restrictionReason, adminRights, bannedRights, _, feedId):
if let _ = accessHash {
if accessHash != nil && (flags & (1 << 12)) == 0 {
return parseTelegramGroupOrChannel(chat: rhs)
} else if let lhs = lhs as? TelegramChannel {
var channelFlags = lhs.flags
@ -128,7 +128,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
}
info = .group(TelegramChannelGroupInfo(flags: infoFlags))
}
return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, peerGroupId: feedId.flatMap { PeerGroupId(rawValue: $0) })
return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, peerGroupId: lhs.peerGroupId)
} else {
return nil
}

View File

@ -61,7 +61,7 @@ final class HistoryViewChannelStateValidationContexts {
if ranges.isEmpty {
ranges = [[id]]
} else {
ranges[rangesToInvalidate.count - 1].append(id)
ranges[ranges.count - 1].append(id)
}
}
@ -122,6 +122,8 @@ final class HistoryViewChannelStateValidationContexts {
var addedRanges: [[MessageId]] = []
for messages in rangesToInvalidate {
for id in messages {
invalidatedMessageIds.insert(id)
if context.batchReferences[id] != nil {
addRangeBreak(&addedRanges)
} else {
@ -141,7 +143,7 @@ final class HistoryViewChannelStateValidationContexts {
context.batchReferences[messageId] = batch
}
disposable.set((validateBatch(postbox: self.postbox, network: self.network, messageIds: messages)
disposable.set((validateBatch(postbox: self.postbox, network: self.network, messageIds: messages, validatePts: invalidatedPts)
|> 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] = []
@ -215,8 +217,10 @@ final class HistoryViewChannelStateValidationContexts {
private func hashForMessages(_ messages: [Message]) -> Int32 {
var acc: UInt32 = 0
for message in messages {
acc = (acc &* 20261) &+ message.id.id
let sorted = messages.sorted(by: { $0.id > $1.id })
for message in sorted {
acc = (acc &* 20261) &+ UInt32(message.id.id)
var timestamp = message.timestamp
inner: for attribute in message.attributes {
if let attribute = attribute as? EditedMessageAttribute {
@ -224,35 +228,169 @@ private func hashForMessages(_ messages: [Message]) -> Int32 {
break inner
}
}
acc = (acc &* 20261) &+ timestamp
acc = (acc &* 20261) &+ UInt32(timestamp)
}
return Int32(bitPattern: acc & UInt32(0x7FFFFFFF))
}
private func validateBatch(postbox: Postbox, network: Network, messageIds: [MessageId]) -> Signal<Void, NoError> {
private func hashForMessages(_ messages: [StoreMessage]) -> Int32 {
var acc: UInt32 = 0
for message in messages {
if case let .Id(id) = message.id {
acc = (acc &* 20261) &+ UInt32(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) &+ UInt32(timestamp)
}
}
return Int32(bitPattern: acc & UInt32(0x7FFFFFFF))
}
private func validateBatch(postbox: Postbox, network: Network, messageIds: [MessageId], validatePts: Int32) -> 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 inputPeer = apiInputPeer(peer) {
var messages: [Message] = []
var previous: [MessageId: Message] = [:]
for messageId in messageIds {
if let message = modifier.getMessage(messageId) {
messages.append(message)
previous[message.id] = message
}
}
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, hash: hash))
return network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: messageIds[messageIds.count - 1].id + 1, offsetDate: 0, addOffset: 0, limit: Int32(messageIds.count), maxId: messageIds[messageIds.count - 1].id + 1, minId: messageIds[0].id - 1, hash: hash))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
if let result = result {
let messages: [Api.Message]
let chats: [Api.Chat]
let users: [Api.User]
var channelPts: Int32?
switch result {
case let .messages(messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .channelMessages(_, pts, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
channelPts = pts
case .messagesNotModified:
break
for id in previous.keys {
modifier.updateMessage(id, 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
/*if let channelPts = channelPts {
for i in 0 ..< attributes.count {
if let _ = attributes[i] as? ChannelMessageStateVersionAttribute {
attributes.remove(at: i)
break
}
}
attributes.append(ChannelMessageStateVersionAttribute(pts: channelPts))
}*/
for i in 0 ..< attributes.count {
if let _ = attributes[i] as? ChannelMessageStateVersionAttribute {
attributes.remove(at: i)
break
}
}
attributes.append(ChannelMessageStateVersionAttribute(pts: validatePts))
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, timestamp: currentMessage.timestamp, flags: [.Failed], tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
}
return
}
var storeMessages: [StoreMessage] = []
for message in messages {
if let storeMessage = StoreMessage(apiMessage: message) {
if let channelPts = channelPts {
var attributes = storeMessage.attributes
attributes.append(ChannelMessageStateVersionAttribute(pts: channelPts))
storeMessages.append(storeMessage.withUpdatedAttributes(attributes))
} else {
storeMessages.append(storeMessage)
}
}
}
//let updatedHash = hashForMessages(storeMessages)
var validMessageIds = Set<MessageId>()
for message in storeMessages {
if case let .Id(id) = message.id {
validMessageIds.insert(id)
if let previousMessage = previous[id] {
var updatedTimestamp = message.timestamp
inner: for attribute in message.attributes {
if let attribute = attribute as? EditedMessageAttribute {
updatedTimestamp = attribute.date
break inner
}
}
var timestamp = previousMessage.timestamp
inner: for attribute in previousMessage.attributes {
if let attribute = attribute as? EditedMessageAttribute {
timestamp = attribute.date
break inner
}
}
modifier.updateMessage(id, update: { currentMessage in
if updatedTimestamp != timestamp {
return .update(message)
} else {
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
if let channelPts = channelPts {
for i in 0 ..< attributes.count {
if let _ = attributes[i] as? ChannelMessageStateVersionAttribute {
attributes.remove(at: i)
break
}
}
attributes.append(ChannelMessageStateVersionAttribute(pts: channelPts))
}
return .update(StoreMessage(id: message.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, timestamp: currentMessage.timestamp, flags: [.Failed], tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
}
})
}
}
}
for id in previous.keys {
if !validMessageIds.contains(id) {
modifier.deleteMessages([id])
}
}
}
}

View File

@ -183,6 +183,10 @@ func fetchMessageHistoryHole(source: FetchMessageHistoryHoleSource, postbox: Pos
chats = apiChats
users = apiUsers
channelPts = pts
case .messagesNotModified:
messages = []
chats = []
users = []
}
var updatedMaxIndex: MessageIndex?
if let maxIndexResult = maxIndexResult {
@ -194,6 +198,8 @@ func fetchMessageHistoryHole(source: FetchMessageHistoryHoleSource, postbox: Pos
maxIndexMessages = apiMessages
case let .channelMessages(_, _, _, apiMessages, _, _):
maxIndexMessages = apiMessages
case .messagesNotModified:
maxIndexMessages = []
}
if !maxIndexMessages.isEmpty {
assert(maxIndexMessages.count == 1)
@ -520,6 +526,10 @@ func fetchCallListHole(network: Network, postbox: Postbox, holeIndex: MessageInd
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
messages = []
chats = []
users = []
}
return postbox.modify { modifier -> Void in
var storeMessages: [StoreMessage] = []

View File

@ -60,12 +60,14 @@ public func getMessagesLoadIfNecessary(_ messageIds:[MessageId], postbox:Postbox
if let signal = signal {
signals.append(signal |> map { result in
switch result {
case let .messages(messages, chats, users):
return (messages, chats, users)
case let .messagesSlice(_, messages, chats, users):
return (messages, chats, users)
case let .channelMessages(_, _, _, messages, chats, users):
return (messages, chats, users)
case let .messages(messages, chats, users):
return (messages, chats, users)
case let .messagesSlice(_, messages, chats, users):
return (messages, chats, users)
case let .channelMessages(_, _, _, messages, chats, users):
return (messages, chats, users)
case .messagesNotModified:
return ([], [], [])
}
} |> `catch` { _ in
return Signal<([Api.Message], [Api.Chat], [Api.User]), NoError>.single(([], [], []))

View File

@ -43,6 +43,8 @@ public func loadedPeerFromMessage(account: Account, peerId: PeerId, messageId: M
apiUsers = users
case let .channelMessages(_, _, _, _, _, users):
apiUsers = users
case .messagesNotModified:
apiUsers = []
}
for user in apiUsers {

View File

@ -75,18 +75,22 @@ public func requestPeerPhotos(account:Account, peerId:PeerId) -> Signal<[Telegra
let chats: [Api.Chat]
let users: [Api.User]
switch result {
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let.messagesSlice(_, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let.messagesSlice(_, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
messages = []
chats = []
users = []
}
return account.postbox.modify { modifier -> [Message] in

View File

@ -117,6 +117,10 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
messages = []
chats = []
users = []
}
return account.postbox.modify { modifier -> [Message] in
@ -183,18 +187,22 @@ public func downloadMessage(account: Account, messageId: MessageId) -> Signal<Me
let chats: [Api.Chat]
let users: [Api.User]
switch result {
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let.messagesSlice(_, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let.messagesSlice(_, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
messages = []
chats = []
users = []
}
let postboxSignal = account.postbox.modify { modifier -> Message? in
@ -249,6 +257,8 @@ public func searchMessageIdByTimestamp(account: Account, peerId: PeerId, timesta
messages = apiMessages
case let.messagesSlice(_, apiMessages, _, _):
messages = apiMessages
case .messagesNotModified:
messages = []
}
for message in messages {
if let message = StoreMessage(apiMessage: message), case let .Id(id) = message.id {

View File

@ -64,6 +64,10 @@ private func fetchMessage(modifier: Modifier, account: Account, messageId: Messa
apiMessages = messages
apiChats = chats
apiUsers = users
case .messagesNotModified:
apiMessages = []
apiChats = []
apiUsers = []
}
var peers: [PeerId: Peer] = [:]

View File

@ -53,6 +53,8 @@ private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId
apiMessages = messages
case let .messagesSlice(_, messages, _, _):
apiMessages = messages
case .messagesNotModified:
apiMessages = []
}
if let message = apiMessages.first, let timestamp = message.timestamp {
return .single((message.rawId, timestamp))