no message

This commit is contained in:
Peter Iakovlev 2018-01-18 11:06:44 +04:00
parent 43043843b2
commit b6a7cc8eb0
4 changed files with 122 additions and 105 deletions

View File

@ -1320,7 +1320,14 @@ private func resetChannels(_ account: Account, peers: [Peer], state: AccountMuta
} }
} }
return account.network.request(Api.functions.messages.getPeerDialogs(peers: inputPeers)) return account.network.request(Api.functions.messages.getPeerDialogs(peers: inputPeers))
|> retryRequest |> map(Optional.init)
|> `catch` { error -> Signal<Api.messages.PeerDialogs?, Void> in
if error.errorDescription == "CHANNEL_PRIVATE" && inputPeers.count == 1 {
return .single(nil)
} else {
return .single(nil)
}
}
|> map { result -> AccountMutableState in |> map { result -> AccountMutableState in
var updatedState = state var updatedState = state
@ -1333,74 +1340,76 @@ private func resetChannels(_ account: Account, peers: [Peer], state: AccountMuta
var channelStates: [PeerId: ChannelState] = [:] var channelStates: [PeerId: ChannelState] = [:]
var notificationSettings: [PeerId: PeerNotificationSettings] = [:] var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
switch result { if let result = result {
case let .peerDialogs(dialogs, messages, chats, users, _): switch result {
dialogsChats.append(contentsOf: chats) case let .peerDialogs(dialogs, messages, chats, users, _):
dialogsUsers.append(contentsOf: users) dialogsChats.append(contentsOf: chats)
dialogsUsers.append(contentsOf: users)
loop: for dialog in dialogs {
let apiPeer: Api.Peer
let apiReadInboxMaxId: Int32
let apiReadOutboxMaxId: Int32
let apiTopMessage: Int32
let apiUnreadCount: Int32
let apiUnreadMentionsCount: Int32
var apiChannelPts: Int32?
let apiNotificationSettings: Api.PeerNotifySettings
switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
apiPeer = peer
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
apiUnreadCount = unreadCount
apiUnreadMentionsCount = unreadMentionsCount
apiNotificationSettings = peerNotificationSettings
apiChannelPts = pts
case .dialogFeed:
assertionFailure()
continue loop
}
let peerId: PeerId loop: for dialog in dialogs {
switch apiPeer { let apiPeer: Api.Peer
case let .peerUser(userId): let apiReadInboxMaxId: Int32
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) let apiReadOutboxMaxId: Int32
case let .peerChat(chatId): let apiTopMessage: Int32
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId) let apiUnreadCount: Int32
case let .peerChannel(channelId): let apiUnreadMentionsCount: Int32
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId) var apiChannelPts: Int32?
} let apiNotificationSettings: Api.PeerNotifySettings
switch dialog {
if readStates[peerId] == nil { case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
readStates[peerId] = [:] apiPeer = peer
} apiTopMessage = topMessage
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount) apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
if apiTopMessage != 0 { apiUnreadCount = unreadCount
mentionTagSummaries[peerId] = MessageHistoryTagNamespaceSummary(version: 1, count: apiUnreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: apiTopMessage)) apiUnreadMentionsCount = unreadMentionsCount
} apiNotificationSettings = peerNotificationSettings
apiChannelPts = pts
if let apiChannelPts = apiChannelPts { case .dialogFeed:
channelStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: apiChannelPts) assertionFailure()
} continue loop
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
}
for message in messages {
if let storeMessage = StoreMessage(apiMessage: message) {
var updatedStoreMessage = storeMessage
if case let .Id(id) = storeMessage.id {
if let channelState = channelStates[id.peerId] {
var updatedAttributes = storeMessage.attributes
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelState.pts))
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
}
} }
storeMessages.append(updatedStoreMessage)
let peerId: PeerId
switch apiPeer {
case let .peerUser(userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .peerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .peerChannel(channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
}
if readStates[peerId] == nil {
readStates[peerId] = [:]
}
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount)
if apiTopMessage != 0 {
mentionTagSummaries[peerId] = MessageHistoryTagNamespaceSummary(version: 1, count: apiUnreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: apiTopMessage))
}
if let apiChannelPts = apiChannelPts {
channelStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: apiChannelPts)
}
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
} }
}
for message in messages {
if let storeMessage = StoreMessage(apiMessage: message) {
var updatedStoreMessage = storeMessage
if case let .Id(id) = storeMessage.id {
if let channelState = channelStates[id.peerId] {
var updatedAttributes = storeMessage.attributes
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelState.pts))
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
}
}
storeMessages.append(updatedStoreMessage)
}
}
}
} }
updatedState.mergeChats(dialogsChats) updatedState.mergeChats(dialogsChats)
@ -1776,10 +1785,16 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
modifier.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id) modifier.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id)
case let .EditMessage(id, message): case let .EditMessage(id, message):
modifier.updateMessage(id, update: { previousMessage in modifier.updateMessage(id, update: { previousMessage in
var updatedFlags = message.flags
var updatedLocalTags = message.localTags var updatedLocalTags = message.localTags
if previousMessage.localTags.contains(.OutgoingLiveLocation) { if previousMessage.localTags.contains(.OutgoingLiveLocation) {
updatedLocalTags.insert(.OutgoingLiveLocation) updatedLocalTags.insert(.OutgoingLiveLocation)
} }
if message.flags.contains(.Incoming) {
updatedFlags.insert(.Incoming)
} else {
updatedFlags.remove(.Incoming)
}
return .update(message.withUpdatedLocalTags(updatedLocalTags)) return .update(message.withUpdatedLocalTags(updatedLocalTags))
}) })
case let .UpdateMedia(id, media): case let .UpdateMedia(id, media):

View File

@ -10,15 +10,15 @@ public typealias AdminLogEventId = Int64
public struct AdminLogEvent { public struct AdminLogEvent {
public let id: AdminLogEventId public let id: AdminLogEventId
public let peerId:PeerId public let peerId: PeerId
public let date:Int32 public let date: Int32
public let action: AdminLogEventAction public let action: AdminLogEventAction
} }
public struct AdminLogEventsResult { public struct AdminLogEventsResult {
public let peerId: PeerId public let peerId: PeerId
public let peers:[PeerId: Peer] public let peers: [PeerId: Peer]
public let events:[AdminLogEvent] public let events: [AdminLogEvent]
} }
public enum AdminLogEventAction { public enum AdminLogEventAction {
@ -29,7 +29,7 @@ public enum AdminLogEventAction {
case toggleInvites(Bool) case toggleInvites(Bool)
case toggleSignatures(Bool) case toggleSignatures(Bool)
case updatePinned(Message?) case updatePinned(Message?)
case editMessage(prev: Message, new:Message) case editMessage(prev: Message, new: Message)
case deleteMessage(Message) case deleteMessage(Message)
case participantJoin case participantJoin
case participantLeave case participantLeave
@ -69,24 +69,24 @@ public struct AdminLogEventsFlags : OptionSet {
public static let editMessages = AdminLogEventsFlags(rawValue: 1 << 12) public static let editMessages = AdminLogEventsFlags(rawValue: 1 << 12)
public static let deleteMessages = AdminLogEventsFlags(rawValue: 1 << 13) public static let deleteMessages = AdminLogEventsFlags(rawValue: 1 << 13)
public static var all:[AdminLogEventsFlags] { public static var all: [AdminLogEventsFlags] {
return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages] return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages]
} }
public static var flags:AdminLogEventsFlags { public static var flags: AdminLogEventsFlags {
return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages] return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages]
} }
} }
private func boolFromApiValue(_ value: Api.Bool) -> Bool { private func boolFromApiValue(_ value: Api.Bool) -> Bool {
switch value { switch value {
case .boolFalse: case .boolFalse:
return false return false
case .boolTrue: case .boolTrue:
return true return true
} }
} }
public func channelAdminLogEvents(_ account:Account, peerId:PeerId, maxId:AdminLogEventId, minId:AdminLogEventId, limit:Int32 = 100, query:String? = nil, filter:AdminLogEventsFlags? = nil, admins:[PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> { public func channelAdminLogEvents(_ account:Account, peerId:PeerId, maxId: AdminLogEventId, minId: AdminLogEventId, limit: Int32 = 100, query: String? = nil, filter: AdminLogEventsFlags? = nil, admins: [PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> {
return account.postbox.modify { modifier -> (Peer?, [Peer]?) in return account.postbox.modify { modifier -> (Peer?, [Peer]?) in
return (modifier.getPeer(peerId), admins?.flatMap {modifier.getPeer($0)}) return (modifier.getPeer(peerId), admins?.flatMap {modifier.getPeer($0)})

View File

@ -132,7 +132,7 @@ final class HistoryViewChannelStateValidationContexts {
} }
} }
if !addedRanges.isEmpty && addedRanges[rangesToInvalidate.count - 1].isEmpty { if !addedRanges.isEmpty && addedRanges[addedRanges.count - 1].isEmpty {
addedRanges.removeLast() addedRanges.removeLast()
} }
@ -318,7 +318,7 @@ private func validateBatch(postbox: Postbox, network: Network, messageIds: [Mess
} }
} }
attributes.append(ChannelMessageStateVersionAttribute(pts: validatePts)) 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 .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))
}) })
} }
return return
@ -380,7 +380,7 @@ private func validateBatch(postbox: Postbox, network: Network, messageIds: [Mess
} }
attributes.append(ChannelMessageStateVersionAttribute(pts: channelPts)) 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)) return .update(StoreMessage(id: message.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))
} }
}) })
} }

View File

@ -119,8 +119,8 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
switch item { switch item {
case let .peer(peerId): case let .peer(peerId):
return peerId.namespace != Namespaces.Peer.SecretChat return peerId.namespace != Namespaces.Peer.SecretChat
case .group: default:
return false return true
} }
} }
let localItemIds = modifier.getPinnedItemIds() let localItemIds = modifier.getPinnedItemIds()
@ -128,17 +128,14 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
switch item { switch item {
case let .peer(peerId): case let .peer(peerId):
return peerId.namespace != Namespaces.Peer.SecretChat return peerId.namespace != Namespaces.Peer.SecretChat
case .group: default:
return false return true
} }
} }
return network.request(Api.functions.messages.getPinnedDialogs()) return network.request(Api.functions.messages.getPinnedDialogs())
|> retryRequest |> retryRequest
|> mapToSignal { dialogs -> Signal<Void, NoError> in |> mapToSignal { dialogs -> Signal<Void, NoError> in
let dialogsChats: [Api.Chat]
let dialogsUsers: [Api.User]
var storeMessages: [StoreMessage] = [] var storeMessages: [StoreMessage] = []
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:] var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
var chatStates: [PeerId: PeerChatState] = [:] var chatStates: [PeerId: PeerChatState] = [:]
@ -146,10 +143,27 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
var remoteItemIds: [PinnedItemId] = [] var remoteItemIds: [PinnedItemId] = []
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
switch dialogs { switch dialogs {
case let .peerDialogs(dialogs, messages, chats, users, _): case let .peerDialogs(dialogs, messages, chats, users, _):
dialogsChats = chats var channelGroupIds: [PeerId: PeerGroupId] = [:]
dialogsUsers = users for chat in chats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers.append(groupOrChannel)
if let channel = groupOrChannel as? TelegramChannel, let peerGroupId = channel.peerGroupId {
channelGroupIds[channel.id] = peerGroupId
}
}
}
for user in users {
let telegramUser = TelegramUser(user: user)
peers.append(telegramUser)
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
}
}
loop: for dialog in dialogs { loop: for dialog in dialogs {
let apiPeer: Api.Peer let apiPeer: Api.Peer
@ -161,6 +175,9 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
let apiNotificationSettings: Api.PeerNotifySettings let apiNotificationSettings: Api.PeerNotifySettings
switch dialog { switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _): case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
if channelGroupIds[peer.peerId] != nil {
continue loop
}
apiPeer = peer apiPeer = peer
apiTopMessage = topMessage apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId apiReadInboxMaxId = readInboxMaxId
@ -204,21 +221,6 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
} }
} }
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for chat in dialogsChats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers.append(groupOrChannel)
}
}
for user in dialogsUsers {
let telegramUser = TelegramUser(user: user)
peers.append(telegramUser)
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
}
}
let locallyRemovedFromRemoteItemIds = Set(initialRemoteItemIdsWithoutSecretChats).subtracting(Set(localItemIdsWithoutSecretChats)) let locallyRemovedFromRemoteItemIds = Set(initialRemoteItemIdsWithoutSecretChats).subtracting(Set(localItemIdsWithoutSecretChats))
let remotelyRemovedItemIds = Set(initialRemoteItemIdsWithoutSecretChats).subtracting(Set(remoteItemIds)) let remotelyRemovedItemIds = Set(initialRemoteItemIdsWithoutSecretChats).subtracting(Set(remoteItemIds))