Rewritten chat grouping

This commit is contained in:
Peter 2019-04-25 21:16:10 +04:00
parent 5a84384da7
commit e7015a1d85
26 changed files with 695 additions and 582 deletions

View File

@ -665,6 +665,8 @@
D0C50E351E93A86600F62E39 /* CallSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C50E331E93A86600F62E39 /* CallSessionManager.swift */; }; D0C50E351E93A86600F62E39 /* CallSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C50E331E93A86600F62E39 /* CallSessionManager.swift */; };
D0CA3F84207391560042D2B6 /* SecureIdPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */; }; D0CA3F84207391560042D2B6 /* SecureIdPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */; };
D0CA3F85207391560042D2B6 /* SecureIdPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */; }; D0CA3F85207391560042D2B6 /* SecureIdPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */; };
D0CA8E4B227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA8E4A227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift */; };
D0CA8E4C227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CA8E4A227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift */; };
D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; }; D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; };
D0D1026C2212FE52003ADA5E /* AccountSortOrderAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */; }; D0D1026C2212FE52003ADA5E /* AccountSortOrderAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */; };
D0D1026D2212FE52003ADA5E /* AccountSortOrderAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */; }; D0D1026D2212FE52003ADA5E /* AccountSortOrderAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */; };
@ -1176,6 +1178,7 @@
D0C48F3B1E8142EF0075317D /* LoadedPeerFromMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedPeerFromMessage.swift; sourceTree = "<group>"; }; D0C48F3B1E8142EF0075317D /* LoadedPeerFromMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedPeerFromMessage.swift; sourceTree = "<group>"; };
D0C50E331E93A86600F62E39 /* CallSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallSessionManager.swift; sourceTree = "<group>"; }; D0C50E331E93A86600F62E39 /* CallSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallSessionManager.swift; sourceTree = "<group>"; };
D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdPadding.swift; sourceTree = "<group>"; }; D0CA3F83207391560042D2B6 /* SecureIdPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdPadding.swift; sourceTree = "<group>"; };
D0CA8E4A227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeGroupMessageStats.swift; sourceTree = "<group>"; };
D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKitDynamic.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKitDynamic.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSortOrderAttribute.swift; sourceTree = "<group>"; }; D0D1026B2212FE52003ADA5E /* AccountSortOrderAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSortOrderAttribute.swift; sourceTree = "<group>"; };
D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackInteractiveOperations.swift; sourceTree = "<group>"; }; D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackInteractiveOperations.swift; sourceTree = "<group>"; };
@ -1574,6 +1577,7 @@
09EDAD3922131D010012A50B /* ManagedAutodownloadSettingsUpdates.swift */, 09EDAD3922131D010012A50B /* ManagedAutodownloadSettingsUpdates.swift */,
093857A72243D87900EB6A54 /* SynchronizeEmojiKeywordsOperation.swift */, 093857A72243D87900EB6A54 /* SynchronizeEmojiKeywordsOperation.swift */,
093857A62243D87800EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift */, 093857A62243D87800EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift */,
D0CA8E4A227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift */,
); );
name = State; name = State;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2208,6 +2212,7 @@
D03229F41E6B39700000AF9C /* ImportAccount.swift in Sources */, D03229F41E6B39700000AF9C /* ImportAccount.swift in Sources */,
D021E0DF1DB539FC00C6B04F /* StickerPack.swift in Sources */, D021E0DF1DB539FC00C6B04F /* StickerPack.swift in Sources */,
D03B0D091D62255C00955575 /* EnqueueMessage.swift in Sources */, D03B0D091D62255C00955575 /* EnqueueMessage.swift in Sources */,
D0CA8E4B227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift in Sources */,
D0DFD5DF1FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */, D0DFD5DF1FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
D093D7EE206413F600BC3599 /* SecureIdDataTypes.swift in Sources */, D093D7EE206413F600BC3599 /* SecureIdDataTypes.swift in Sources */,
D00D343C1E6EC9770057B307 /* TelegramMediaGame.swift in Sources */, D00D343C1E6EC9770057B307 /* TelegramMediaGame.swift in Sources */,
@ -2944,6 +2949,7 @@
D02ABC7F1E3109F000CAE539 /* CloudChatRemoveMessagesOperation.swift in Sources */, D02ABC7F1E3109F000CAE539 /* CloudChatRemoveMessagesOperation.swift in Sources */,
D0528E611E65B94E00E2FEF5 /* SingleMessageView.swift in Sources */, D0528E611E65B94E00E2FEF5 /* SingleMessageView.swift in Sources */,
D0FC195C2020D1CA00FEDBB2 /* PeerGroupMessageStateVersionAttribute.swift in Sources */, D0FC195C2020D1CA00FEDBB2 /* PeerGroupMessageStateVersionAttribute.swift in Sources */,
D0CA8E4C227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift in Sources */,
D08CAA851ED8164B0000FDA8 /* Localization.swift in Sources */, D08CAA851ED8164B0000FDA8 /* Localization.swift in Sources */,
D0528E5B1E658B3600E2FEF5 /* ManagedLocalInputActivities.swift in Sources */, D0528E5B1E658B3600E2FEF5 /* ManagedLocalInputActivities.swift in Sources */,
D0FA8BA51E1FA341001E855B /* SecretChatKeychain.swift in Sources */, D0FA8BA51E1FA341001E855B /* SecretChatKeychain.swift in Sources */,

View File

@ -264,7 +264,7 @@ let telegramPostboxSeedConfiguration: SeedConfiguration = {
} else { } else {
return [.regularChatsAndPrivateGroups] return [.regularChatsAndPrivateGroups]
} }
}, additionalChatListIndexNamespace: Namespaces.Message.Cloud) }, additionalChatListIndexNamespace: Namespaces.Message.Cloud, messageNamespacesRequiringGroupStatsValidation: [Namespaces.Message.Cloud])
}() }()
public func accountPreferenceEntries(rootPath: String, id: AccountRecordId, keys: Set<ValueBoxKey>, encryptionParameters: ValueBoxEncryptionParameters) -> Signal<(String, [ValueBoxKey: PreferencesEntry]), NoError> { public func accountPreferenceEntries(rootPath: String, id: AccountRecordId, keys: Set<ValueBoxKey>, encryptionParameters: ValueBoxEncryptionParameters) -> Signal<(String, [ValueBoxKey: PreferencesEntry]), NoError> {
@ -985,6 +985,7 @@ public class Account {
self.accountPresenceManager = AccountPresenceManager(shouldKeepOnlinePresence: self.shouldKeepOnlinePresence.get(), network: network) self.accountPresenceManager = AccountPresenceManager(shouldKeepOnlinePresence: self.shouldKeepOnlinePresence.get(), network: network)
let _ = (postbox.transaction { transaction -> Void in let _ = (postbox.transaction { transaction -> Void in
transaction.updatePeerPresencesInternal(presences: [peerId: TelegramUserPresence(status: .present(until: Int32.max - 1), lastActivity: 0)], merge: { _, updated in return updated }) transaction.updatePeerPresencesInternal(presences: [peerId: TelegramUserPresence(status: .present(until: Int32.max - 1), lastActivity: 0)], merge: { _, updated in return updated })
transaction.setNeedsPeerGroupMessageStatsSynchronization(groupId: Namespaces.PeerGroup.archive, namespace: Namespaces.Message.Cloud)
}).start() }).start()
self.notificationAutolockReportManager = NotificationAutolockReportManager(deadline: self.autolockReportDeadline.get(), network: network) self.notificationAutolockReportManager = NotificationAutolockReportManager(deadline: self.autolockReportDeadline.get(), network: network)
self.autolockReportDeadline.set( self.autolockReportDeadline.set(

View File

@ -9,22 +9,26 @@ import Foundation
import MtProtoKitDynamic import MtProtoKitDynamic
#endif #endif
struct PeerChatInfo {
var notificationSettings: PeerNotificationSettings
}
final class AccountInitialState { final class AccountInitialState {
let state: AuthorizedAccountState.State let state: AuthorizedAccountState.State
let peerIds: Set<PeerId> let peerIds: Set<PeerId>
let chatStates: [PeerId: PeerChatState] let chatStates: [PeerId: PeerChatState]
let peerNotificationSettings: [PeerId: PeerNotificationSettings] let peerChatInfos: [PeerId: PeerChatInfo]
let peerIdsWithNewMessages: Set<PeerId> let peerIdsRequiringLocalChatState: Set<PeerId>
let locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]] let locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]
let cloudReadStates: [PeerId: PeerReadState] let cloudReadStates: [PeerId: PeerReadState]
let channelsToPollExplicitely: Set<PeerId> let channelsToPollExplicitely: Set<PeerId>
init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, peerIdsWithNewMessages: Set<PeerId>, chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState], channelsToPollExplicitely: Set<PeerId>) { init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, peerIdsRequiringLocalChatState: Set<PeerId>, chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState], channelsToPollExplicitely: Set<PeerId>) {
self.state = state self.state = state
self.peerIds = peerIds self.peerIds = peerIds
self.chatStates = chatStates self.chatStates = chatStates
self.peerIdsWithNewMessages = peerIdsWithNewMessages self.peerIdsRequiringLocalChatState = peerIdsRequiringLocalChatState
self.peerNotificationSettings = peerNotificationSettings self.peerChatInfos = peerChatInfos
self.locallyGeneratedMessageTimestamps = locallyGeneratedMessageTimestamps self.locallyGeneratedMessageTimestamps = locallyGeneratedMessageTimestamps
self.cloudReadStates = cloudReadStates self.cloudReadStates = cloudReadStates
self.channelsToPollExplicitely = channelsToPollExplicitely self.channelsToPollExplicitely = channelsToPollExplicitely
@ -81,7 +85,7 @@ enum AccountStateMutationOperation {
case AddSecretMessages([Api.EncryptedMessage]) case AddSecretMessages([Api.EncryptedMessage])
case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32) case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32)
case AddPeerInputActivity(chatPeerId: PeerId, peerId: PeerId?, activity: PeerInputActivity?) case AddPeerInputActivity(chatPeerId: PeerId, peerId: PeerId?, activity: PeerInputActivity?)
case UpdatePinnedItemIds(PeerGroupId?, AccountStateUpdatePinnedItemIdsOperation) case UpdatePinnedItemIds(PeerGroupId, AccountStateUpdatePinnedItemIdsOperation)
case ReadMessageContents((PeerId?, [Int32])) case ReadMessageContents((PeerId?, [Int32]))
case UpdateMessageImpressionCount(MessageId, Int32) case UpdateMessageImpressionCount(MessageId, Int32)
case UpdateInstalledStickerPacks(AccountStateUpdateStickerPacksOperation) case UpdateInstalledStickerPacks(AccountStateUpdateStickerPacksOperation)
@ -90,8 +94,7 @@ enum AccountStateMutationOperation {
case UpdateCall(Api.PhoneCall) case UpdateCall(Api.PhoneCall)
case UpdateLangPack(String, Api.LangPackDifference?) case UpdateLangPack(String, Api.LangPackDifference?)
case UpdateMinAvailableMessage(MessageId) case UpdateMinAvailableMessage(MessageId)
case UpdatePeerInclusionMinTimestamp(PeerId, Int32) case UpdatePeerChatInclusion(PeerId, PeerGroupId)
case UpdatePeerGroup(PeerId, PeerGroupId?)
} }
struct AccountMutableState { struct AccountMutableState {
@ -103,7 +106,7 @@ struct AccountMutableState {
var state: AuthorizedAccountState.State var state: AuthorizedAccountState.State
var peers: [PeerId: Peer] var peers: [PeerId: Peer]
var chatStates: [PeerId: PeerChatState] var chatStates: [PeerId: PeerChatState]
var peerNotificationSettings: [PeerId: PeerNotificationSettings] var peerChatInfos: [PeerId: PeerChatInfo]
var referencedMessageIds: Set<MessageId> var referencedMessageIds: Set<MessageId>
var storedMessages: Set<MessageId> var storedMessages: Set<MessageId>
var readInboxMaxIds: [PeerId: MessageId] var readInboxMaxIds: [PeerId: MessageId]
@ -127,13 +130,13 @@ struct AccountMutableState {
self.storedMessages = initialStoredMessages self.storedMessages = initialStoredMessages
self.readInboxMaxIds = initialReadInboxMaxIds self.readInboxMaxIds = initialReadInboxMaxIds
self.chatStates = initialState.chatStates self.chatStates = initialState.chatStates
self.peerNotificationSettings = initialState.peerNotificationSettings self.peerChatInfos = initialState.peerChatInfos
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.branchOperationIndex = 0 self.branchOperationIndex = 0
self.namespacesWithHolesFromPreviousState = [:] self.namespacesWithHolesFromPreviousState = [:]
} }
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) { init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], 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
@ -141,7 +144,7 @@ struct AccountMutableState {
self.chatStates = chatStates self.chatStates = chatStates
self.referencedMessageIds = referencedMessageIds self.referencedMessageIds = referencedMessageIds
self.storedMessages = storedMessages self.storedMessages = storedMessages
self.peerNotificationSettings = peerNotificationSettings self.peerChatInfos = peerChatInfos
self.readInboxMaxIds = readInboxMaxIds self.readInboxMaxIds = readInboxMaxIds
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.namespacesWithHolesFromPreviousState = namespacesWithHolesFromPreviousState self.namespacesWithHolesFromPreviousState = namespacesWithHolesFromPreviousState
@ -150,7 +153,7 @@ struct AccountMutableState {
} }
func branch() -> AccountMutableState { func branch() -> AccountMutableState {
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerNotificationSettings: self.peerNotificationSettings, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count) return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerChatInfos: self.peerChatInfos, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count)
} }
mutating func merge(_ other: AccountMutableState) { mutating func merge(_ other: AccountMutableState) {
@ -279,12 +282,8 @@ struct AccountMutableState {
self.addOperation(.UpdateMinAvailableMessage(id)) self.addOperation(.UpdateMinAvailableMessage(id))
} }
mutating func updatePeerInclusionMinTimestamp(peerId: PeerId, timestamp: Int32) { mutating func updatePeerChatInclusion(peerId: PeerId, groupId: PeerGroupId) {
self.addOperation(.UpdatePeerInclusionMinTimestamp(peerId, timestamp)) self.addOperation(.UpdatePeerChatInclusion(peerId, groupId))
}
mutating func updatePeerGroup(peerId: PeerId, groupId: PeerGroupId?) {
self.addOperation(.UpdatePeerGroup(peerId, groupId))
} }
mutating func mergeUsers(_ users: [Api.User]) { mutating func mergeUsers(_ users: [Api.User]) {
@ -327,7 +326,7 @@ struct AccountMutableState {
self.addOperation(.AddPeerInputActivity(chatPeerId: chatPeerId, peerId: peerId, activity: activity)) self.addOperation(.AddPeerInputActivity(chatPeerId: chatPeerId, peerId: peerId, activity: activity))
} }
mutating func addUpdatePinnedItemIds(groupId: PeerGroupId?, operation: AccountStateUpdatePinnedItemIdsOperation) { mutating func addUpdatePinnedItemIds(groupId: PeerGroupId, operation: AccountStateUpdatePinnedItemIdsOperation) {
self.addOperation(.UpdatePinnedItemIds(groupId, operation)) self.addOperation(.UpdatePinnedItemIds(groupId, operation))
} }
@ -357,7 +356,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerInclusionMinTimestamp, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerGroup: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion:
break break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {
@ -389,7 +388,10 @@ struct AccountMutableState {
self.chatStates[peerId] = channelState self.chatStates[peerId] = channelState
case let .UpdateNotificationSettings(subject, notificationSettings): case let .UpdateNotificationSettings(subject, notificationSettings):
if case let .peer(peerId) = subject { if case let .peer(peerId) = subject {
self.peerNotificationSettings[peerId] = notificationSettings if var currentInfo = self.peerChatInfos[peerId] {
currentInfo.notificationSettings = notificationSettings
self.peerChatInfos[peerId] = currentInfo
}
} }
case .UpdateGlobalNotificationSettings: case .UpdateGlobalNotificationSettings:
break break

View File

@ -72,22 +72,39 @@ private func associatedMessageIdsFromUpdateGroups(_ groups: [UpdateGroup]) -> Se
return messageIds return messageIds
} }
private func peersWithNewMessagesFromUpdateGroups(_ groups: [UpdateGroup]) -> Set<PeerId> { private func peerIdsRequiringLocalChatStateFromUpdates(_ updates: [Api.Update]) -> Set<PeerId> {
var peerIds = Set<PeerId>()
for update in updates {
if let messageId = update.messageId {
peerIds.insert(messageId.peerId)
}
switch update {
case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
peerIds.insert(peerId)
case let .updateFolderPeers(folderPeers, _, _):
for peer in folderPeers {
switch peer {
case let .folderPeer(peer, _):
peerIds.insert(peer.peerId)
}
}
case let .updateReadChannelInbox(_, _, channelId, _, _, _):
peerIds.insert(PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId))
case let .updateReadHistoryInbox(_, _, peer, _, _, _, _):
peerIds.insert(peer.peerId)
default:
break
}
}
return peerIds
}
private func peerIdsRequiringLocalChatStateFromUpdateGroups(_ groups: [UpdateGroup]) -> Set<PeerId> {
var peerIds = Set<PeerId>() var peerIds = Set<PeerId>()
for group in groups { for group in groups {
for update in group.updates { peerIds.formUnion(peerIdsRequiringLocalChatStateFromUpdates(group.updates))
if let messageId = update.messageId {
peerIds.insert(messageId.peerId)
}
switch update {
case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
peerIds.insert(peerId)
default:
break
}
}
} }
return peerIds return peerIds
@ -239,7 +256,7 @@ private func associatedMessageIdsFromDifference(_ difference: Api.updates.Differ
return messageIds return messageIds
} }
private func peersWithNewMessagesFromDifference(_ difference: Api.updates.Difference) -> Set<PeerId> { private func peerIdsRequiringLocalChatStateFromDifference(_ difference: Api.updates.Difference) -> Set<PeerId> {
var peerIds = Set<PeerId>() var peerIds = Set<PeerId>()
switch difference { switch difference {
@ -249,6 +266,7 @@ private func peersWithNewMessagesFromDifference(_ difference: Api.updates.Differ
peerIds.insert(messageId.peerId) peerIds.insert(messageId.peerId)
} }
} }
peerIds.formUnion(peerIdsRequiringLocalChatStateFromUpdates(otherUpdates))
for update in otherUpdates { for update in otherUpdates {
if let messageId = update.messageId { if let messageId = update.messageId {
peerIds.insert(messageId.peerId) peerIds.insert(messageId.peerId)
@ -270,6 +288,7 @@ private func peersWithNewMessagesFromDifference(_ difference: Api.updates.Differ
} }
} }
peerIds.formUnion(peerIdsRequiringLocalChatStateFromUpdates(otherUpdates))
for update in otherUpdates { for update in otherUpdates {
if let messageId = update.messageId { if let messageId = update.messageId {
peerIds.insert(messageId.peerId) peerIds.insert(messageId.peerId)
@ -325,7 +344,7 @@ private func locallyGeneratedMessageTimestampsFromDifference(_ difference: Api.u
return messageTimestamps return messageTimestamps
} }
private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<PeerId>, activeChannelIds: Set<PeerId>, associatedMessageIds: Set<MessageId>, peerIdsWithNewMessages: Set<PeerId>, locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]) -> AccountMutableState { private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<PeerId>, activeChannelIds: Set<PeerId>, associatedMessageIds: Set<MessageId>, peerIdsRequiringLocalChatState: Set<PeerId>, locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]) -> AccountMutableState {
var peers: [PeerId: Peer] = [:] var peers: [PeerId: Peer] = [:]
var chatStates: [PeerId: PeerChatState] = [:] var chatStates: [PeerId: PeerChatState] = [:]
@ -371,13 +390,23 @@ private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<Pe
} }
} }
var peerNotificationSettings: [PeerId: PeerNotificationSettings] = [:] var peerChatInfos: [PeerId: PeerChatInfo] = [:]
var readInboxMaxIds: [PeerId: MessageId] = [:] var readInboxMaxIds: [PeerId: MessageId] = [:]
var cloudReadStates: [PeerId: PeerReadState] = [:] var cloudReadStates: [PeerId: PeerReadState] = [:]
for peerId in peerIdsWithNewMessages { for peerId in peerIdsRequiringLocalChatState {
if let notificationSettings = transaction.getPeerNotificationSettings(peerId) { let inclusion = transaction.getPeerChatListInclusion(peerId)
peerNotificationSettings[peerId] = notificationSettings var hasValidInclusion = false
switch inclusion {
case .ifHasMessagesOrOneOf:
hasValidInclusion = true
case .notIncluded:
hasValidInclusion = false
}
if hasValidInclusion {
if let notificationSettings = transaction.getPeerNotificationSettings(peerId) {
peerChatInfos[peerId] = PeerChatInfo(notificationSettings: notificationSettings)
}
} }
if let readStates = transaction.getPeerReadStates(peerId) { if let readStates = transaction.getPeerReadStates(peerId) {
for (namespace, state) in readStates { for (namespace, state) in readStates {
@ -395,7 +424,7 @@ private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<Pe
} }
} }
return AccountMutableState(initialState: AccountInitialState(state: (transaction.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, peerIdsWithNewMessages: peerIdsWithNewMessages, chatStates: chatStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates, channelsToPollExplicitely: channelsToPollExplicitely), initialPeers: peers, initialReferencedMessageIds: associatedMessageIds, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp) return AccountMutableState(initialState: AccountInitialState(state: (transaction.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, peerIdsRequiringLocalChatState: peerIdsRequiringLocalChatState, chatStates: chatStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates, channelsToPollExplicitely: channelsToPollExplicitely), initialPeers: peers, initialReferencedMessageIds: associatedMessageIds, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp)
} }
func initialStateWithUpdateGroups(postbox: Postbox, groups: [UpdateGroup]) -> Signal<AccountMutableState, NoError> { func initialStateWithUpdateGroups(postbox: Postbox, groups: [UpdateGroup]) -> Signal<AccountMutableState, NoError> {
@ -403,9 +432,9 @@ func initialStateWithUpdateGroups(postbox: Postbox, groups: [UpdateGroup]) -> Si
let peerIds = peerIdsFromUpdateGroups(groups) let peerIds = peerIdsFromUpdateGroups(groups)
let activeChannelIds = activeChannelsFromUpdateGroups(groups) let activeChannelIds = activeChannelsFromUpdateGroups(groups)
let associatedMessageIds = associatedMessageIdsFromUpdateGroups(groups) let associatedMessageIds = associatedMessageIdsFromUpdateGroups(groups)
let peerIdsWithNewMessages = peersWithNewMessagesFromUpdateGroups(groups) let peerIdsRequiringLocalChatState = peerIdsRequiringLocalChatStateFromUpdateGroups(groups)
return initialStateWithPeerIds(transaction, peerIds: peerIds, activeChannelIds: activeChannelIds, associatedMessageIds: associatedMessageIds, peerIdsWithNewMessages: peerIdsWithNewMessages, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestampsFromUpdateGroups(groups)) return initialStateWithPeerIds(transaction, peerIds: peerIds, activeChannelIds: activeChannelIds, associatedMessageIds: associatedMessageIds, peerIdsRequiringLocalChatState: peerIdsRequiringLocalChatState, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestampsFromUpdateGroups(groups))
} }
} }
@ -414,8 +443,8 @@ func initialStateWithDifference(postbox: Postbox, difference: Api.updates.Differ
let peerIds = peerIdsFromDifference(difference) let peerIds = peerIdsFromDifference(difference)
let activeChannelIds = activeChannelsFromDifference(difference) let activeChannelIds = activeChannelsFromDifference(difference)
let associatedMessageIds = associatedMessageIdsFromDifference(difference) let associatedMessageIds = associatedMessageIdsFromDifference(difference)
let peerIdsWithNewMessages = peersWithNewMessagesFromDifference(difference) let peerIdsRequiringLocalChatState = peerIdsRequiringLocalChatStateFromDifference(difference)
return initialStateWithPeerIds(transaction, peerIds: peerIds, activeChannelIds: activeChannelIds, associatedMessageIds: associatedMessageIds, peerIdsWithNewMessages: peerIdsWithNewMessages, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestampsFromDifference(difference)) return initialStateWithPeerIds(transaction, peerIds: peerIds, activeChannelIds: activeChannelIds, associatedMessageIds: associatedMessageIds, peerIdsRequiringLocalChatState: peerIdsRequiringLocalChatState, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestampsFromDifference(difference))
} }
} }
@ -930,11 +959,11 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
} else { } else {
updatedState.addDisplayAlert(text, isDropAuth: type.hasPrefix("AUTH_KEY_DROP_")) updatedState.addDisplayAlert(text, isDropAuth: type.hasPrefix("AUTH_KEY_DROP_"))
} }
case let .updateReadChannelInbox(channelId, maxId): case let .updateReadChannelInbox(_, folderId, channelId, maxId, stillUnreadCount, pts):
updatedState.readInbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId)) updatedState.readInbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId))
case let .updateReadChannelOutbox(channelId, maxId): case let .updateReadChannelOutbox(channelId, maxId):
updatedState.readOutbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId), timestamp: nil) updatedState.readOutbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId), timestamp: nil)
case let .updateReadHistoryInbox(peer, maxId, _, _): case let .updateReadHistoryInbox(_, folderId, peer, maxId, stillUnreadCount, _, _):
updatedState.readInbox(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: maxId)) updatedState.readInbox(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: maxId))
case let .updateReadHistoryOutbox(peer, maxId, _, _): case let .updateReadHistoryOutbox(peer, maxId, _, _):
updatedState.readOutbox(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: maxId), timestamp: updatesDate) updatedState.readOutbox(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: maxId), timestamp: updatesDate)
@ -1164,7 +1193,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.addPeerInputActivity(chatPeerId: PeerId(namespace: Namespaces.Peer.SecretChat, id: chatId), peerId: nil, activity: .typingText) updatedState.addPeerInputActivity(chatPeerId: PeerId(namespace: Namespaces.Peer.SecretChat, id: chatId), peerId: nil, activity: .typingText)
} }
case let .updateDialogPinned(flags, folderId, peer): case let .updateDialogPinned(flags, folderId, peer):
let groupId: PeerGroupId? = folderId.flatMap(PeerGroupId.init(rawValue:)) let groupId: PeerGroupId = folderId.flatMap(PeerGroupId.init(rawValue:)) ?? .root
let item: PinnedItemId let item: PinnedItemId
switch peer { switch peer {
case let .dialogPeer(peer): case let .dialogPeer(peer):
@ -1178,7 +1207,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .unpin(item)) updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .unpin(item))
} }
case let .updatePinnedDialogs(_, folderId, order): case let .updatePinnedDialogs(_, folderId, order):
let groupId: PeerGroupId? = folderId.flatMap(PeerGroupId.init(rawValue:)) let groupId: PeerGroupId = folderId.flatMap(PeerGroupId.init(rawValue:)) ?? .root
if let order = order { if let order = order {
updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .reorder(order.map { updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .reorder(order.map {
let item: PinnedItemId let item: PinnedItemId
@ -1243,7 +1272,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
for folderPeer in folderPeers { for folderPeer in folderPeers {
switch folderPeer { switch folderPeer {
case let .folderPeer(peer, folderId): case let .folderPeer(peer, folderId):
updatedState.updatePeerGroup(peerId: peer.peerId, groupId: folderId == 0 ? nil : PeerGroupId(rawValue: folderId)) updatedState.updatePeerChatInclusion(peerId: peer.peerId, groupId: PeerGroupId(rawValue: folderId))
} }
} }
default: default:
@ -1299,12 +1328,9 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
} }
return resolveAssociatedMessages(network: network, state: finalState) return resolveAssociatedMessages(network: network, state: finalState)
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in |> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
return resolveMissingPeerNotificationSettings(network: network, state: resultingState) return resolveMissingPeerChatInfos(network: network, state: resultingState)
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in |> map { resultingState -> AccountFinalState in
return resolveMissingPeerCloudReadStates(postbox: postbox, network: network, state: resultingState) return AccountFinalState(state: resultingState, shouldPoll: shouldPoll || hadError, incomplete: missingUpdates)
|> map { resultingState -> AccountFinalState in
return AccountFinalState(state: resultingState, shouldPoll: shouldPoll || hadError, incomplete: missingUpdates)
}
} }
} }
} }
@ -1376,15 +1402,15 @@ private func resolveAssociatedMessages(network: Network, state: AccountMutableSt
} }
} }
private func resolveMissingPeerNotificationSettings(network: Network, state: AccountMutableState) -> Signal<AccountMutableState, NoError> { private func resolveMissingPeerChatInfos(network: Network, state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
var missingPeers: [PeerId: Api.InputPeer] = [:] var missingPeers: [PeerId: Api.InputPeer] = [:]
for peerId in state.initialState.peerIdsWithNewMessages { for peerId in state.initialState.peerIdsRequiringLocalChatState {
if state.peerNotificationSettings[peerId] == nil { if state.peerChatInfos[peerId] == nil {
if let peer = state.peers[peerId], let inputPeer = apiInputPeer(peer) { if let peer = state.peers[peerId], let inputPeer = apiInputPeer(peer) {
missingPeers[peerId] = inputPeer missingPeers[peerId] = inputPeer
} else { } else {
Logger.shared.log("State", "can't fetch notification settings for peer \(peerId): can't create inputPeer") Logger.shared.log("State", "can't fetch chat info for peer \(peerId): can't create inputPeer")
} }
} }
} }
@ -1392,66 +1418,71 @@ private func resolveMissingPeerNotificationSettings(network: Network, state: Acc
if missingPeers.isEmpty { if missingPeers.isEmpty {
return .single(state) return .single(state)
} else { } else {
Logger.shared.log("State", "will fetch notification settings for \(missingPeers.count) peers") Logger.shared.log("State", "will fetch chat info for \(missingPeers.count) peers")
var signals: [Signal<(PeerId, PeerNotificationSettings)?, NoError>] = [] let signal = network.request(Api.functions.messages.getPeerDialogs(peers: missingPeers.values.map(Api.InputDialogPeer.inputDialogPeer(peer:))))
for (peerId, peer) in missingPeers { |> map(Optional.init)
let fetchSettings = network.request(Api.functions.account.getNotifySettings(peer: .inputNotifyPeer(peer: peer)))
|> map { settings -> (PeerId, PeerNotificationSettings)? in
return (peerId, TelegramPeerNotificationSettings(apiSettings: settings))
}
|> `catch` { _ -> Signal<(PeerId, PeerNotificationSettings)?, NoError> in
return .single(nil)
}
signals.append(fetchSettings)
}
return combineLatest(signals)
|> map { peersAndSettings -> AccountMutableState in
var updatedState = state
for pair in peersAndSettings {
if let (peerId, settings) = pair {
updatedState.updateNotificationSettings(.peer(peerId), notificationSettings: settings)
}
}
return updatedState
}
}
}
private func resolveMissingPeerCloudReadStates(postbox: Postbox, network: Network, state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
var missingPeers: [PeerId: Api.InputPeer] = [:]
for peerId in state.initialState.peerIdsWithNewMessages {
if state.initialState.cloudReadStates[peerId] == nil && (peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup) {
if let peer = state.peers[peerId], let inputPeer = apiInputPeer(peer) {
missingPeers[peerId] = inputPeer
} else {
Logger.shared.log("State", "can't fetch notification settings for peer \(peerId): can't create inputPeer")
}
}
}
if missingPeers.isEmpty {
return .single(state)
} else {
Logger.shared.log("State", "will fetch cloud read states for \(missingPeers.count) peers")
var signals: [Signal<(PeerId, PeerReadState)?, NoError>] = [] return signal
for (peerId, inputPeer) in missingPeers { |> `catch` { _ -> Signal<Api.messages.PeerDialogs?, NoError> in
let fetchSettings = fetchPeerCloudReadState(network: network, postbox: postbox, peerId: peerId, inputPeer: inputPeer) return .single(nil)
|> map { state -> (PeerId, PeerReadState)? in
return state.flatMap { (peerId, $0) }
}
signals.append(fetchSettings)
} }
return combineLatest(signals) |> map { result -> AccountMutableState in
|> map { peersAndSettings -> AccountMutableState in guard let result = result else {
return state
}
var channelStates: [PeerId: ChannelState] = [:]
var updatedState = state var updatedState = state
for pair in peersAndSettings { switch result {
if let (peerId, state) = pair { case let .peerDialogs(dialogs, messages, chats, users, state):
if case let .idBased(maxIncomingReadId, maxOutgoingReadId, maxKnownId, count, markedUnread) = state { updatedState.mergeChats(chats)
updatedState.resetReadState(peerId, namespace: Namespaces.Message.Cloud, maxIncomingReadId: maxIncomingReadId, maxOutgoingReadId: maxOutgoingReadId, maxKnownId: maxKnownId, count: count, markedUnread: markedUnread) updatedState.mergeUsers(users)
var topMessageIds = Set<MessageId>()
for dialog in dialogs {
switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, notifySettings, pts, draft, folderId):
updatedState.setNeedsHoleFromPreviousState(peerId: peer.peerId, namespace: Namespaces.Message.Cloud)
if topMessage != 0 {
topMessageIds.insert(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: topMessage))
}
updatedState.updatePeerChatInclusion(peerId: peer.peerId, groupId: PeerGroupId(rawValue: folderId ?? 0))
updatedState.updateNotificationSettings(.peer(peer.peerId), notificationSettings: TelegramPeerNotificationSettings(apiSettings: notifySettings))
updatedState.resetReadState(peer.peerId, namespace: Namespaces.Message.Cloud, maxIncomingReadId: readInboxMaxId, maxOutgoingReadId: readOutboxMaxId, maxKnownId: topMessage, count: unreadCount, markedUnread: nil)
updatedState.resetMessageTagSummary(peer.peerId, namespace: Namespaces.Message.Cloud, count: unreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: topMessage))
if let pts = pts {
channelStates[peer.peerId] = ChannelState(pts: pts, invalidatedPts: pts)
}
case .dialogFolder:
assertionFailure()
break
}
}
var storeMessages: [StoreMessage] = []
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)
}
}
for message in storeMessages {
if case let .Id(id) = message.id {
updatedState.addMessages([message], location: topMessageIds.contains(id) ? .UpperHistoryBlock : .Random)
}
} }
}
} }
return updatedState return updatedState
} }
@ -1466,16 +1497,26 @@ func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stat
chatStates[peerId] = channelState chatStates[peerId] = channelState
} }
let initialPeers: [PeerId: Peer] = [peerId: peer] let initialPeers: [PeerId: Peer] = [peerId: peer]
var peerNotificationSettings: [PeerId: TelegramPeerNotificationSettings] = [:] var peerChatInfos: [PeerId: PeerChatInfo] = [:]
if let notificationSettings = transaction.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings { let inclusion = transaction.getPeerChatListInclusion(peerId)
peerNotificationSettings[peerId] = notificationSettings var hasValidInclusion = false
switch inclusion {
case .ifHasMessagesOrOneOf:
hasValidInclusion = true
case .notIncluded:
hasValidInclusion = false
} }
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsWithNewMessages: Set(), chatStates: chatStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:]) if hasValidInclusion {
if let notificationSettings = transaction.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings {
peerChatInfos[peerId] = PeerChatInfo(notificationSettings: notificationSettings)
}
}
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), chatStates: chatStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
return pollChannel(network: network, peer: peer, state: initialState) return pollChannel(network: network, peer: peer, state: initialState)
|> mapToSignal { (finalState, _, timeout) -> Signal<Void, NoError> in |> mapToSignal { (finalState, _, timeout) -> Signal<Void, NoError> in
return resolveAssociatedMessages(network: network, state: finalState) return resolveAssociatedMessages(network: network, state: finalState)
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in |> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
return resolveMissingPeerNotificationSettings(network: network, state: resultingState) return resolveMissingPeerChatInfos(network: network, state: resultingState)
|> map { resultingState -> AccountFinalState in |> map { resultingState -> AccountFinalState in
return AccountFinalState(state: resultingState, shouldPoll: false, incomplete: false) return AccountFinalState(state: resultingState, shouldPoll: false, incomplete: false)
} }
@ -1540,6 +1581,7 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
var apiChannelPts: Int32? var apiChannelPts: Int32?
let apiNotificationSettings: Api.PeerNotifySettings let apiNotificationSettings: Api.PeerNotifySettings
let apiMarkedUnread: Bool let apiMarkedUnread: Bool
let groupId: PeerGroupId
switch dialog { switch dialog {
case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _, folderId): case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _, folderId):
apiPeer = peer apiPeer = peer
@ -1551,6 +1593,7 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
apiUnreadMentionsCount = unreadMentionsCount apiUnreadMentionsCount = unreadMentionsCount
apiNotificationSettings = peerNotificationSettings apiNotificationSettings = peerNotificationSettings
apiChannelPts = pts apiChannelPts = pts
groupId = PeerGroupId(rawValue: folderId ?? 0)
case .dialogFolder: case .dialogFolder:
assertionFailure() assertionFailure()
continue loop continue loop
@ -1580,6 +1623,8 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
} }
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings) notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
updatedState.updatePeerChatInclusion(peerId: peerId, groupId: groupId)
} }
for message in messages { for message in messages {
@ -1892,7 +1937,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddMessages: OptimizeAddMessagesState? var currentAddMessages: OptimizeAddMessagesState?
for operation in operations { for operation in operations {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerInclusionMinTimestamp, .UpdatePeerGroup, .UpdateIsContact: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
} }
@ -1961,8 +2006,6 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
var delayNotificatonsUntil: Int32? var delayNotificatonsUntil: Int32?
var peerActivityTimestamps: [PeerId: Int32] = [:] var peerActivityTimestamps: [PeerId: Int32] = [:]
var addHolesToGroupFeedIds = Set<PeerGroupId>()
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState { for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
for namespace in namespaces { for namespace in namespaces {
if let id = transaction.getTopPeerMessageId(peerId: peerId, namespace: namespace) { if let id = transaction.getTopPeerMessageId(peerId: peerId, namespace: namespace) {
@ -1970,30 +2013,9 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
} else { } else {
transaction.addHole(peerId: peerId, namespace: namespace, space: .everywhere, range: 1 ... Int32.max) transaction.addHole(peerId: peerId, namespace: namespace, space: .everywhere, range: 1 ... Int32.max)
} }
if namespace == Namespaces.Message.Cloud {
let peer: Peer? = finalState.state.peers[peerId] ?? transaction.getPeer(peerId)
if let peer = peer {
var groupId: PeerGroupId?
if groupId == nil {
//groupId = transaction.getPeerGroupId(peerId)
}
if let groupId = groupId {
addHolesToGroupFeedIds.insert(groupId)
}
} else {
assertionFailure()
}
}
} }
} }
/*for groupId in addHolesToGroupFeedIds {
transaction.addFeedHoleFromLatestEntries(groupId: groupId)
let groupState = (transaction.getPeerGroupState(groupId) as? TelegramPeerGroupState) ?? TelegramPeerGroupState()
transaction.setPeerGroupState(groupId, state: groupState.withInvalidatedStateIndex())
}*/
var addedOperationIncomingMessageIds: [MessageId] = [] var addedOperationIncomingMessageIds: [MessageId] = []
for operation in finalState.state.operations { for operation in finalState.state.operations {
switch operation { switch operation {
@ -2107,16 +2129,18 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp) updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp)
} }
transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id) transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id)
case let .UpdatePeerInclusionMinTimestamp(peerId, timestamp): case let .UpdatePeerChatInclusion(peerId, groupId):
let inclusion = transaction.getPeerChatListInclusion(peerId) let currentInclusion = transaction.getPeerChatListInclusion(peerId)
switch inclusion { var currentPinningIndex: UInt16?
case .ifHasMessages, .ifHasMessagesOrOneOf: var currentMinTimestamp: Int32?
transaction.updatePeerChatListInclusion(peerId, inclusion: inclusion.withSetIfHasMessagesOrMaxMinTimestamp(timestamp)) switch currentInclusion {
case let .ifHasMessagesOrOneOf(_, pinningIndex, minTimestamp):
currentPinningIndex = pinningIndex
currentMinTimestamp = minTimestamp
default: default:
break break
} }
case let .UpdatePeerGroup(peerId, groupId): transaction.updatePeerChatListInclusion(peerId, inclusion: .ifHasMessagesOrOneOf(groupId: groupId, pinningIndex: currentPinningIndex, minTimestamp: currentMinTimestamp))
transaction.updatePeerGroupId(peerId, groupId: groupId)
case let .EditMessage(id, message): case let .EditMessage(id, message):
transaction.updateMessage(id, update: { previousMessage in transaction.updateMessage(id, update: { previousMessage in
var updatedFlags = message.flags var updatedFlags = message.flags
@ -2311,7 +2335,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
case let .pin(itemId): case let .pin(itemId):
switch itemId { switch itemId {
case let .peer(peerId): case let .peer(peerId):
if transaction.getPeer(peerId) == nil || transaction.getPeerChatListInclusion(peerId) == .notSpecified { if transaction.getPeer(peerId) == nil || transaction.getPeerChatListInclusion(peerId) == .notIncluded {
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId) addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
} else { } else {
var currentItemIds = transaction.getPinnedItemIds(groupId: groupId) var currentItemIds = transaction.getPinnedItemIds(groupId: groupId)
@ -2320,8 +2344,6 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
transaction.setPinnedItemIds(groupId: groupId, itemIds: currentItemIds) transaction.setPinnedItemIds(groupId: groupId, itemIds: currentItemIds)
} }
} }
case .group:
break
} }
case let .unpin(itemId): case let .unpin(itemId):
switch itemId { switch itemId {
@ -2333,8 +2355,6 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
} else { } else {
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId) addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
} }
case .group:
break
} }
case let .reorder(itemIds): case let .reorder(itemIds):
let currentItemIds = transaction.getPinnedItemIds(groupId: groupId) let currentItemIds = transaction.getPinnedItemIds(groupId: groupId)
@ -2399,10 +2419,6 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
updatePeerPresenceLastActivities(transaction: transaction, accountPeerId: accountPeerId, activities: peerActivityTimestamps) updatePeerPresenceLastActivities(transaction: transaction, accountPeerId: accountPeerId, activities: peerActivityTimestamps)
} }
for peerId in finalState.state.initialState.peerIdsWithNewMessages {
updatePeerChatInclousionWithNewMessages(transaction: transaction, id: peerId)
}
if !stickerPackOperations.isEmpty { if !stickerPackOperations.isEmpty {
if stickerPackOperations.contains(where: { if stickerPackOperations.contains(where: {
if case .sync = $0 { if case .sync = $0 {

View File

@ -96,8 +96,8 @@ public final class AccountStateManager {
return self.isUpdatingValue.get() return self.isUpdatingValue.get()
} }
private let notificationMessagesPipe = ValuePipe<[([Message], PeerGroupId?, Bool)]>() private let notificationMessagesPipe = ValuePipe<[([Message], PeerGroupId, Bool)]>()
public var notificationMessages: Signal<[([Message], PeerGroupId?, Bool)], NoError> { public var notificationMessages: Signal<[([Message], PeerGroupId, Bool)], NoError> {
return self.notificationMessagesPipe.signal() return self.notificationMessagesPipe.signal()
} }
@ -385,9 +385,11 @@ public final class AccountStateManager {
|> mapToSignal { difference -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in |> mapToSignal { difference -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
switch difference { switch difference {
case .differenceTooLong: case .differenceTooLong:
return accountStateReset(postbox: postbox, network: network, accountPeerId: accountPeerId) |> mapToSignal { _ -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in preconditionFailure()
/*return accountStateReset(postbox: postbox, network: network, accountPeerId: accountPeerId) |> mapToSignal { _ -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
return .complete() return .complete()
} |> then(.single((nil, nil))) }
|> then(.single((nil, nil)))*/
default: default:
return initialStateWithDifference(postbox: postbox, difference: difference) return initialStateWithDifference(postbox: postbox, difference: difference)
|> mapToSignal { state -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in |> mapToSignal { state -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
@ -625,13 +627,12 @@ public final class AccountStateManager {
let _ = self.delayNotificatonsUntil.swap(events.delayNotificatonsUntil) let _ = self.delayNotificatonsUntil.swap(events.delayNotificatonsUntil)
} }
let signal = self.postbox.transaction { transaction -> [([Message], PeerGroupId?, Bool)] in let signal = self.postbox.transaction { transaction -> [([Message], PeerGroupId, Bool)] in
var messageList: [([Message], PeerGroupId?, Bool)] = [] var messageList: [([Message], PeerGroupId, Bool)] = []
for id in events.addedIncomingMessageIds { for id in events.addedIncomingMessageIds {
let (messages, notify, _, _) = messagesForNotification(transaction: transaction, id: id, alwaysReturnMessage: false) let (messages, notify, _, _) = messagesForNotification(transaction: transaction, id: id, alwaysReturnMessage: false)
if !messages.isEmpty { if !messages.isEmpty {
messageList.append((messages, nil, notify)) messageList.append((messages, .root, notify))
//messageList.append((messages, transaction.getPeerGroupId(messages[0].id.peerId), notify))
} }
} }
return messageList return messageList

View File

@ -123,14 +123,14 @@ private struct ResolvedChatListResetRange {
let remote: FetchedChatList let remote: FetchedChatList
} }
func accountStateReset(postbox: Postbox, network: Network, accountPeerId: PeerId) -> Signal<Void, NoError> { /*func accountStateReset(postbox: Postbox, network: Network, accountPeerId: PeerId) -> Signal<Void, NoError> {
let pinnedChats: Signal<Api.messages.PeerDialogs, NoError> = network.request(Api.functions.messages.getPinnedDialogs(folderId: 0)) let pinnedChats: Signal<Api.messages.PeerDialogs, NoError> = network.request(Api.functions.messages.getPinnedDialogs(folderId: 0))
|> retryRequest |> retryRequest
let state: Signal<Api.updates.State, NoError> = network.request(Api.functions.updates.getState()) let state: Signal<Api.updates.State, NoError> = network.request(Api.functions.updates.getState())
|> retryRequest |> retryRequest
return postbox.transaction { transaction -> [ChatListNamespaceEntry] in return postbox.transaction { transaction -> [ChatListNamespaceEntry] in
return transaction.getChatListNamespaceEntries(groupId: nil, namespace: Namespaces.Message.Cloud, summaryTag: MessageTags.unseenPersonalMessage) return transaction.getChatListNamespaceEntries(groupId: .root, namespace: Namespaces.Message.Cloud, summaryTag: MessageTags.unseenPersonalMessage)
} }
|> mapToSignal { localChatListEntries -> Signal<Void, NoError> in |> mapToSignal { localChatListEntries -> Signal<Void, NoError> in
let localRanges = localChatListEntryRanges(localChatListEntries, limit: 100) let localRanges = localChatListEntryRanges(localChatListEntries, limit: 100)
@ -292,4 +292,4 @@ func accountStateReset(postbox: Postbox, network: Network, accountPeerId: PeerId
} }
} }
} }
} }*/

View File

@ -1169,7 +1169,7 @@ public final class AccountViewTracker {
}) })
} }
public func tailChatListView(groupId: PeerGroupId?, count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> { public func tailChatListView(groupId: PeerGroupId, count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> {
if let account = self.account { if let account = self.account {
return self.wrappedChatListView(signal: account.postbox.tailChatListView(groupId: groupId, count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud)))) return self.wrappedChatListView(signal: account.postbox.tailChatListView(groupId: groupId, count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud))))
} else { } else {
@ -1177,7 +1177,7 @@ public final class AccountViewTracker {
} }
} }
public func aroundChatListView(groupId: PeerGroupId?, index: ChatListIndex, count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> { public func aroundChatListView(groupId: PeerGroupId, index: ChatListIndex, count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> {
if let account = self.account { if let account = self.account {
return self.wrappedChatListView(signal: account.postbox.aroundChatListView(groupId: groupId, index: index, count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud)))) return self.wrappedChatListView(signal: account.postbox.aroundChatListView(groupId: groupId, index: index, count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud))))
} else { } else {

View File

@ -9,8 +9,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) } dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) } dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) } dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[478652186] = { return Api.ChatFull.parse_channelFull($0) } dict[461151667] = { return Api.ChatFull.parse_chatFull($0) }
dict[581055962] = { return Api.ChatFull.parse_chatFull($0) } dict[56920439] = { return Api.ChatFull.parse_channelFull($0) }
dict[1465219162] = { return Api.PollResults.parse_pollResults($0) } dict[1465219162] = { return Api.PollResults.parse_pollResults($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) } dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) }
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) } dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
@ -94,7 +94,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[483104362] = { return Api.RichText.parse_textPhone($0) } dict[483104362] = { return Api.RichText.parse_textPhone($0) }
dict[136105807] = { return Api.RichText.parse_textImage($0) } dict[136105807] = { return Api.RichText.parse_textImage($0) }
dict[894777186] = { return Api.RichText.parse_textAnchor($0) } dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
dict[-1901811583] = { return Api.UserFull.parse_userFull($0) } dict[1951750604] = { return Api.UserFull.parse_userFull($0) }
dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) } dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) }
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) } dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
dict[414687501] = { return Api.DcOption.parse_dcOption($0) } dict[414687501] = { return Api.DcOption.parse_dcOption($0) }
@ -184,14 +184,12 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) } dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
dict[-298113238] = { return Api.Update.parse_updatePrivacy($0) } dict[-298113238] = { return Api.Update.parse_updatePrivacy($0) }
dict[314130811] = { return Api.Update.parse_updateUserPhone($0) } dict[314130811] = { return Api.Update.parse_updateUserPhone($0) }
dict[-1721631396] = { return Api.Update.parse_updateReadHistoryInbox($0) }
dict[791617983] = { return Api.Update.parse_updateReadHistoryOutbox($0) } dict[791617983] = { return Api.Update.parse_updateReadHistoryOutbox($0) }
dict[2139689491] = { return Api.Update.parse_updateWebPage($0) } dict[2139689491] = { return Api.Update.parse_updateWebPage($0) }
dict[1757493555] = { return Api.Update.parse_updateReadMessagesContents($0) } dict[1757493555] = { return Api.Update.parse_updateReadMessagesContents($0) }
dict[-352032773] = { return Api.Update.parse_updateChannelTooLong($0) } dict[-352032773] = { return Api.Update.parse_updateChannelTooLong($0) }
dict[-1227598250] = { return Api.Update.parse_updateChannel($0) } dict[-1227598250] = { return Api.Update.parse_updateChannel($0) }
dict[1656358105] = { return Api.Update.parse_updateNewChannelMessage($0) } dict[1656358105] = { return Api.Update.parse_updateNewChannelMessage($0) }
dict[1108669311] = { return Api.Update.parse_updateReadChannelInbox($0) }
dict[-1015733815] = { return Api.Update.parse_updateDeleteChannelMessages($0) } dict[-1015733815] = { return Api.Update.parse_updateDeleteChannelMessages($0) }
dict[-1734268085] = { return Api.Update.parse_updateChannelMessageViews($0) } dict[-1734268085] = { return Api.Update.parse_updateChannelMessageViews($0) }
dict[-1232070311] = { return Api.Update.parse_updateChatParticipantAdmin($0) } dict[-1232070311] = { return Api.Update.parse_updateChatParticipantAdmin($0) }
@ -232,6 +230,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[422972864] = { return Api.Update.parse_updateFolderPeers($0) } dict[422972864] = { return Api.Update.parse_updateFolderPeers($0) }
dict[1852826908] = { return Api.Update.parse_updateDialogPinned($0) } dict[1852826908] = { return Api.Update.parse_updateDialogPinned($0) }
dict[-99664734] = { return Api.Update.parse_updatePinnedDialogs($0) } dict[-99664734] = { return Api.Update.parse_updatePinnedDialogs($0) }
dict[856380452] = { return Api.Update.parse_updateReadChannelInbox($0) }
dict[-1667805217] = { return Api.Update.parse_updateReadHistoryInbox($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) } dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }

View File

@ -50,14 +50,33 @@ extension Api {
} }
enum ChatFull: TypeConstructorDescription { enum ChatFull: TypeConstructorDescription {
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?) case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?)
case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?) case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, pts: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId):
if boxed { if boxed {
buffer.appendInt32(478652186) buffer.appendInt32(461151667)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeString(about, buffer: buffer, boxed: false)
participants.serialize(buffer, true)
if Int(flags) & Int(1 << 2) != 0 {chatPhoto!.serialize(buffer, true)}
notifySettings.serialize(buffer, true)
exportedInvite.serialize(buffer, true)
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(botInfo!.count))
for item in botInfo! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
break
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let pts):
if boxed {
buffer.appendInt32(56920439)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
@ -83,37 +102,69 @@ extension Api {
if Int(flags) & Int(1 << 5) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 5) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 8) != 0 {stickerset!.serialize(buffer, true)} if Int(flags) & Int(1 << 8) != 0 {stickerset!.serialize(buffer, true)}
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(availableMinId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 9) != 0 {serializeInt32(availableMinId!, buffer: buffer, boxed: false)}
break if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId): serializeInt32(pts, buffer: buffer, boxed: false)
if boxed {
buffer.appendInt32(581055962)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeString(about, buffer: buffer, boxed: false)
participants.serialize(buffer, true)
if Int(flags) & Int(1 << 2) != 0 {chatPhoto!.serialize(buffer, true)}
notifySettings.serialize(buffer, true)
exportedInvite.serialize(buffer, true)
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(botInfo!.count))
for item in botInfo! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
break break
} }
} }
func descriptionFields() -> (String, [(String, Any)]) { func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId):
return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId)]) return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId)])
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let pts):
return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId)]) return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("pts", pts)])
} }
} }
static func parse_chatFull(_ reader: BufferReader) -> ChatFull? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: String?
_3 = parseString(reader)
var _4: Api.ChatParticipants?
if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatParticipants
}
var _5: Api.Photo?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _6: Api.PeerNotifySettings?
if let signature = reader.readInt32() {
_6 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
}
var _7: Api.ExportedChatInvite?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.ExportedChatInvite
}
var _8: [Api.BotInfo]?
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotInfo.self)
} }
var _9: Int32?
if Int(_1!) & Int(1 << 6) != 0 {_9 = reader.readInt32() }
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 6) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7!, botInfo: _8, pinnedMsgId: _9, folderId: _10)
}
else {
return nil
}
}
static func parse_channelFull(_ reader: BufferReader) -> ChatFull? { static func parse_channelFull(_ reader: BufferReader) -> ChatFull? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()
@ -165,6 +216,10 @@ extension Api {
} } } }
var _20: Int32? var _20: Int32?
if Int(_1!) & Int(1 << 9) != 0 {_20 = reader.readInt32() } if Int(_1!) & Int(1 << 9) != 0 {_20 = reader.readInt32() }
var _21: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_21 = reader.readInt32() }
var _22: Int32?
_22 = reader.readInt32()
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
@ -185,53 +240,10 @@ extension Api {
let _c18 = (Int(_1!) & Int(1 << 5) == 0) || _18 != nil let _c18 = (Int(_1!) & Int(1 << 5) == 0) || _18 != nil
let _c19 = (Int(_1!) & Int(1 << 8) == 0) || _19 != nil let _c19 = (Int(_1!) & Int(1 << 8) == 0) || _19 != nil
let _c20 = (Int(_1!) & Int(1 << 9) == 0) || _20 != nil let _c20 = (Int(_1!) & Int(1 << 9) == 0) || _20 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 { let _c21 = (Int(_1!) & Int(1 << 11) == 0) || _21 != nil
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20) let _c22 = _22 != nil
} if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 {
else { return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, pts: _22!)
return nil
}
}
static func parse_chatFull(_ reader: BufferReader) -> ChatFull? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: String?
_3 = parseString(reader)
var _4: Api.ChatParticipants?
if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatParticipants
}
var _5: Api.Photo?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _6: Api.PeerNotifySettings?
if let signature = reader.readInt32() {
_6 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
}
var _7: Api.ExportedChatInvite?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.ExportedChatInvite
}
var _8: [Api.BotInfo]?
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotInfo.self)
} }
var _9: Int32?
if Int(_1!) & Int(1 << 6) != 0 {_9 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 6) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7!, botInfo: _8, pinnedMsgId: _9)
} }
else { else {
return nil return nil
@ -2510,13 +2522,13 @@ extension Api {
} }
enum UserFull: TypeConstructorDescription { enum UserFull: TypeConstructorDescription {
case userFull(flags: Int32, user: Api.User, about: String?, link: Api.contacts.Link, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32) case userFull(flags: Int32, user: Api.User, about: String?, link: Api.contacts.Link, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .userFull(let flags, let user, let about, let link, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount): case .userFull(let flags, let user, let about, let link, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId):
if boxed { if boxed {
buffer.appendInt32(-1901811583) buffer.appendInt32(1951750604)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
user.serialize(buffer, true) user.serialize(buffer, true)
@ -2527,14 +2539,15 @@ extension Api {
if Int(flags) & Int(1 << 3) != 0 {botInfo!.serialize(buffer, true)} if Int(flags) & Int(1 << 3) != 0 {botInfo!.serialize(buffer, true)}
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
serializeInt32(commonChatsCount, buffer: buffer, boxed: false) serializeInt32(commonChatsCount, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
break break
} }
} }
func descriptionFields() -> (String, [(String, Any)]) { func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .userFull(let flags, let user, let about, let link, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount): case .userFull(let flags, let user, let about, let link, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId):
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("link", link), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount)]) return ("userFull", [("flags", flags), ("user", user), ("about", about), ("link", link), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId)])
} }
} }
@ -2567,6 +2580,8 @@ extension Api {
if Int(_1!) & Int(1 << 6) != 0 {_8 = reader.readInt32() } if Int(_1!) & Int(1 << 6) != 0 {_8 = reader.readInt32() }
var _9: Int32? var _9: Int32?
_9 = reader.readInt32() _9 = reader.readInt32()
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
@ -2576,8 +2591,9 @@ extension Api {
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
let _c8 = (Int(_1!) & Int(1 << 6) == 0) || _8 != nil let _c8 = (Int(_1!) & Int(1 << 6) == 0) || _8 != nil
let _c9 = _9 != nil let _c9 = _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 { let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, link: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, link: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10)
} }
else { else {
return nil return nil
@ -3924,14 +3940,12 @@ extension Api {
case updateServiceNotification(flags: Int32, inboxDate: Int32?, type: String, message: String, media: Api.MessageMedia, entities: [Api.MessageEntity]) case updateServiceNotification(flags: Int32, inboxDate: Int32?, type: String, message: String, media: Api.MessageMedia, entities: [Api.MessageEntity])
case updatePrivacy(key: Api.PrivacyKey, rules: [Api.PrivacyRule]) case updatePrivacy(key: Api.PrivacyKey, rules: [Api.PrivacyRule])
case updateUserPhone(userId: Int32, phone: String) case updateUserPhone(userId: Int32, phone: String)
case updateReadHistoryInbox(peer: Api.Peer, maxId: Int32, pts: Int32, ptsCount: Int32)
case updateReadHistoryOutbox(peer: Api.Peer, maxId: Int32, pts: Int32, ptsCount: Int32) case updateReadHistoryOutbox(peer: Api.Peer, maxId: Int32, pts: Int32, ptsCount: Int32)
case updateWebPage(webpage: Api.WebPage, pts: Int32, ptsCount: Int32) case updateWebPage(webpage: Api.WebPage, pts: Int32, ptsCount: Int32)
case updateReadMessagesContents(messages: [Int32], pts: Int32, ptsCount: Int32) case updateReadMessagesContents(messages: [Int32], pts: Int32, ptsCount: Int32)
case updateChannelTooLong(flags: Int32, channelId: Int32, pts: Int32?) case updateChannelTooLong(flags: Int32, channelId: Int32, pts: Int32?)
case updateChannel(channelId: Int32) case updateChannel(channelId: Int32)
case updateNewChannelMessage(message: Api.Message, pts: Int32, ptsCount: Int32) case updateNewChannelMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateReadChannelInbox(channelId: Int32, maxId: Int32)
case updateDeleteChannelMessages(channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32) case updateDeleteChannelMessages(channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32)
case updateChannelMessageViews(channelId: Int32, id: Int32, views: Int32) case updateChannelMessageViews(channelId: Int32, id: Int32, views: Int32)
case updateChatParticipantAdmin(chatId: Int32, userId: Int32, isAdmin: Api.Bool, version: Int32) case updateChatParticipantAdmin(chatId: Int32, userId: Int32, isAdmin: Api.Bool, version: Int32)
@ -3972,6 +3986,8 @@ extension Api {
case updateFolderPeers(folderPeers: [Api.FolderPeer], pts: Int32, ptsCount: Int32) case updateFolderPeers(folderPeers: [Api.FolderPeer], pts: Int32, ptsCount: Int32)
case updateDialogPinned(flags: Int32, folderId: Int32?, peer: Api.DialogPeer) case updateDialogPinned(flags: Int32, folderId: Int32?, peer: Api.DialogPeer)
case updatePinnedDialogs(flags: Int32, folderId: Int32?, order: [Api.DialogPeer]?) case updatePinnedDialogs(flags: Int32, folderId: Int32?, order: [Api.DialogPeer]?)
case updateReadChannelInbox(flags: Int32, folderId: Int32?, channelId: Int32, maxId: Int32, stillUnreadCount: Int32, pts: Int32)
case updateReadHistoryInbox(flags: Int32, folderId: Int32?, peer: Api.Peer, maxId: Int32, stillUnreadCount: Int32, pts: Int32, ptsCount: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -4159,15 +4175,6 @@ extension Api {
serializeInt32(userId, buffer: buffer, boxed: false) serializeInt32(userId, buffer: buffer, boxed: false)
serializeString(phone, buffer: buffer, boxed: false) serializeString(phone, buffer: buffer, boxed: false)
break break
case .updateReadHistoryInbox(let peer, let maxId, let pts, let ptsCount):
if boxed {
buffer.appendInt32(-1721631396)
}
peer.serialize(buffer, true)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
break
case .updateReadHistoryOutbox(let peer, let maxId, let pts, let ptsCount): case .updateReadHistoryOutbox(let peer, let maxId, let pts, let ptsCount):
if boxed { if boxed {
buffer.appendInt32(791617983) buffer.appendInt32(791617983)
@ -4219,13 +4226,6 @@ extension Api {
serializeInt32(pts, buffer: buffer, boxed: false) serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false) serializeInt32(ptsCount, buffer: buffer, boxed: false)
break break
case .updateReadChannelInbox(let channelId, let maxId):
if boxed {
buffer.appendInt32(1108669311)
}
serializeInt32(channelId, buffer: buffer, boxed: false)
serializeInt32(maxId, buffer: buffer, boxed: false)
break
case .updateDeleteChannelMessages(let channelId, let messages, let pts, let ptsCount): case .updateDeleteChannelMessages(let channelId, let messages, let pts, let ptsCount):
if boxed { if boxed {
buffer.appendInt32(-1015733815) buffer.appendInt32(-1015733815)
@ -4557,6 +4557,29 @@ extension Api {
item.serialize(buffer, true) item.serialize(buffer, true)
}} }}
break break
case .updateReadChannelInbox(let flags, let folderId, let channelId, let maxId, let stillUnreadCount, let pts):
if boxed {
buffer.appendInt32(856380452)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
serializeInt32(channelId, buffer: buffer, boxed: false)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(stillUnreadCount, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
break
case .updateReadHistoryInbox(let flags, let folderId, let peer, let maxId, let stillUnreadCount, let pts, let ptsCount):
if boxed {
buffer.appendInt32(-1667805217)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
peer.serialize(buffer, true)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(stillUnreadCount, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
break
} }
} }
@ -4606,8 +4629,6 @@ extension Api {
return ("updatePrivacy", [("key", key), ("rules", rules)]) return ("updatePrivacy", [("key", key), ("rules", rules)])
case .updateUserPhone(let userId, let phone): case .updateUserPhone(let userId, let phone):
return ("updateUserPhone", [("userId", userId), ("phone", phone)]) return ("updateUserPhone", [("userId", userId), ("phone", phone)])
case .updateReadHistoryInbox(let peer, let maxId, let pts, let ptsCount):
return ("updateReadHistoryInbox", [("peer", peer), ("maxId", maxId), ("pts", pts), ("ptsCount", ptsCount)])
case .updateReadHistoryOutbox(let peer, let maxId, let pts, let ptsCount): case .updateReadHistoryOutbox(let peer, let maxId, let pts, let ptsCount):
return ("updateReadHistoryOutbox", [("peer", peer), ("maxId", maxId), ("pts", pts), ("ptsCount", ptsCount)]) return ("updateReadHistoryOutbox", [("peer", peer), ("maxId", maxId), ("pts", pts), ("ptsCount", ptsCount)])
case .updateWebPage(let webpage, let pts, let ptsCount): case .updateWebPage(let webpage, let pts, let ptsCount):
@ -4620,8 +4641,6 @@ extension Api {
return ("updateChannel", [("channelId", channelId)]) return ("updateChannel", [("channelId", channelId)])
case .updateNewChannelMessage(let message, let pts, let ptsCount): case .updateNewChannelMessage(let message, let pts, let ptsCount):
return ("updateNewChannelMessage", [("message", message), ("pts", pts), ("ptsCount", ptsCount)]) return ("updateNewChannelMessage", [("message", message), ("pts", pts), ("ptsCount", ptsCount)])
case .updateReadChannelInbox(let channelId, let maxId):
return ("updateReadChannelInbox", [("channelId", channelId), ("maxId", maxId)])
case .updateDeleteChannelMessages(let channelId, let messages, let pts, let ptsCount): case .updateDeleteChannelMessages(let channelId, let messages, let pts, let ptsCount):
return ("updateDeleteChannelMessages", [("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) return ("updateDeleteChannelMessages", [("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)])
case .updateChannelMessageViews(let channelId, let id, let views): case .updateChannelMessageViews(let channelId, let id, let views):
@ -4702,6 +4721,10 @@ extension Api {
return ("updateDialogPinned", [("flags", flags), ("folderId", folderId), ("peer", peer)]) return ("updateDialogPinned", [("flags", flags), ("folderId", folderId), ("peer", peer)])
case .updatePinnedDialogs(let flags, let folderId, let order): case .updatePinnedDialogs(let flags, let folderId, let order):
return ("updatePinnedDialogs", [("flags", flags), ("folderId", folderId), ("order", order)]) return ("updatePinnedDialogs", [("flags", flags), ("folderId", folderId), ("order", order)])
case .updateReadChannelInbox(let flags, let folderId, let channelId, let maxId, let stillUnreadCount, let pts):
return ("updateReadChannelInbox", [("flags", flags), ("folderId", folderId), ("channelId", channelId), ("maxId", maxId), ("stillUnreadCount", stillUnreadCount), ("pts", pts)])
case .updateReadHistoryInbox(let flags, let folderId, let peer, let maxId, let stillUnreadCount, let pts, let ptsCount):
return ("updateReadHistoryInbox", [("flags", flags), ("folderId", folderId), ("peer", peer), ("maxId", maxId), ("stillUnreadCount", stillUnreadCount), ("pts", pts), ("ptsCount", ptsCount)])
} }
} }
@ -5095,28 +5118,6 @@ extension Api {
return nil return nil
} }
} }
static func parse_updateReadHistoryInbox(_ reader: BufferReader) -> Update? {
var _1: Api.Peer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.Update.updateReadHistoryInbox(peer: _1!, maxId: _2!, pts: _3!, ptsCount: _4!)
}
else {
return nil
}
}
static func parse_updateReadHistoryOutbox(_ reader: BufferReader) -> Update? { static func parse_updateReadHistoryOutbox(_ reader: BufferReader) -> Update? {
var _1: Api.Peer? var _1: Api.Peer?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -5224,20 +5225,6 @@ extension Api {
return nil return nil
} }
} }
static func parse_updateReadChannelInbox(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.Update.updateReadChannelInbox(channelId: _1!, maxId: _2!)
}
else {
return nil
}
}
static func parse_updateDeleteChannelMessages(_ reader: BufferReader) -> Update? { static func parse_updateDeleteChannelMessages(_ reader: BufferReader) -> Update? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()
@ -5885,6 +5872,63 @@ extension Api {
return nil return nil
} }
} }
static func parse_updateReadChannelInbox(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.Update.updateReadChannelInbox(flags: _1!, folderId: _2, channelId: _3!, maxId: _4!, stillUnreadCount: _5!, pts: _6!)
}
else {
return nil
}
}
static func parse_updateReadHistoryInbox(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
var _3: Api.Peer?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.Update.updateReadHistoryInbox(flags: _1!, folderId: _2, peer: _3!, maxId: _4!, stillUnreadCount: _5!, pts: _6!, ptsCount: _7!)
}
else {
return nil
}
}
} }
enum PopularContact: TypeConstructorDescription { enum PopularContact: TypeConstructorDescription {

View File

@ -159,8 +159,8 @@ public func clearPeerUnseenPersonalMessagesInteractively(account: Account, peerI
|> ignoreValues |> ignoreValues
} }
public func markAllChatsAsReadInteractively(transaction: Transaction, viewTracker: AccountViewTracker) { public func markAllChatsAsReadInteractively(transaction: Transaction, viewTracker: AccountViewTracker, groupId: PeerGroupId) {
for peerId in transaction.getUnreadChatListPeerIds() { for peerId in transaction.getUnreadChatListPeerIds(groupId: groupId) {
togglePeerUnreadMarkInteractively(transaction: transaction, viewTracker: viewTracker, peerId: peerId, setToValue: false) togglePeerUnreadMarkInteractively(transaction: transaction, viewTracker: viewTracker, peerId: peerId, setToValue: false)
} }
} }

View File

@ -189,7 +189,7 @@ final class ChatHistoryPreloadManager {
self.accountPeerId = accountPeerId self.accountPeerId = accountPeerId
self.download.set(network.background()) self.download.set(network.background())
self.automaticChatListDisposable = (postbox.tailChatListView(groupId: nil, count: 20, summaryComponents: ChatListEntrySummaryComponents()) self.automaticChatListDisposable = (postbox.tailChatListView(groupId: .root, count: 20, summaryComponents: ChatListEntrySummaryComponents())
|> deliverOnMainQueue).start(next: { [weak self] view in |> deliverOnMainQueue).start(next: { [weak self] view in
guard let strongSelf = self else { guard let strongSelf = self else {
return return

View File

@ -15,7 +15,7 @@ enum FetchChatListLocation {
} }
struct ParsedDialogs { struct ParsedDialogs {
let itemIds: [PinnedItemId] let itemIds: [PeerId]
let peers: [Peer] let peers: [Peer]
let peerPresences: [PeerId: PeerPresence] let peerPresences: [PeerId: PeerPresence]
@ -27,7 +27,7 @@ struct ParsedDialogs {
let storeMessages: [StoreMessage] let storeMessages: [StoreMessage]
let lowerNonPinnedIndex: MessageIndex? let lowerNonPinnedIndex: MessageIndex?
let referencedFolders: [PeerGroupId] let referencedFolders: [PeerGroupId: PeerGroupUnreadCountersSummary]
} }
private func extractDialogsData(dialogs: Api.messages.Dialogs) -> (apiDialogs: [Api.Dialog], apiMessages: [Api.Message], apiChats: [Api.Chat], apiUsers: [Api.User], apiIsAtLowestBoundary: Bool) { private func extractDialogsData(dialogs: Api.messages.Dialogs) -> (apiDialogs: [Api.Dialog], apiMessages: [Api.Message], apiChats: [Api.Chat], apiUsers: [Api.User], apiIsAtLowestBoundary: Bool) {
@ -59,8 +59,8 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
var storeMessages: [StoreMessage] = [] var storeMessages: [StoreMessage] = []
var nonPinnedDialogsTopMessageIds = Set<MessageId>() var nonPinnedDialogsTopMessageIds = Set<MessageId>()
var referencedFolders = Set<PeerGroupId>() var referencedFolders: [PeerGroupId: PeerGroupUnreadCountersSummary] = [:]
var itemIds: [PinnedItemId] = [] var itemIds: [PeerId] = []
for dialog in apiDialogs { for dialog in apiDialogs {
let apiPeer: Api.Peer let apiPeer: Api.Peer
@ -74,7 +74,7 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
let apiNotificationSettings: Api.PeerNotifySettings let apiNotificationSettings: Api.PeerNotifySettings
switch dialog { switch dialog {
case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _, _): case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _, _):
itemIds.append(.peer(peer.peerId)) itemIds.append(peer.peerId)
apiPeer = peer apiPeer = peer
apiTopMessage = topMessage apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId apiReadInboxMaxId = readInboxMaxId
@ -113,13 +113,11 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
} }
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings) notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
case let .dialogFolder(flags, folder, _, _, _, _, _, _): case let .dialogFolder(dialogFolder):
switch folder { switch dialogFolder.folder {
case let .folder(flags, id, title, photo): case let .folder(folder):
referencedFolders.insert(PeerGroupId(rawValue: id)) referencedFolders[PeerGroupId(rawValue: folder.id)] = PeerGroupUnreadCountersSummary(all: PeerGroupUnreadCounters(messageCount: dialogFolder.unreadMutedMessagesCount, chatCount: dialogFolder.unreadMutedPeersCount))
break
} }
break
} }
} }
@ -174,11 +172,12 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
storeMessages: storeMessages, storeMessages: storeMessages,
lowerNonPinnedIndex: lowerNonPinnedIndex, lowerNonPinnedIndex: lowerNonPinnedIndex,
referencedFolders: Array(referencedFolders) referencedFolders: referencedFolders
) )
} }
struct FetchedChatList { struct FetchedChatList {
let chatPeerIds: [PeerId]
let peers: [Peer] let peers: [Peer]
let peerPresences: [PeerId: PeerPresence] let peerPresences: [PeerId: PeerPresence]
let notificationSettings: [PeerId: PeerNotificationSettings] let notificationSettings: [PeerId: PeerNotificationSettings]
@ -190,8 +189,8 @@ struct FetchedChatList {
let lowerNonPinnedIndex: MessageIndex? let lowerNonPinnedIndex: MessageIndex?
let pinnedItemIds: [PinnedItemId]? let pinnedItemIds: [PeerId]?
let folders: [(PeerGroupId, MessageIndex?)] let folderSummaries: [PeerGroupId: PeerGroupUnreadCountersSummary]
let peerGroupIds: [PeerId: PeerGroupId] let peerGroupIds: [PeerId: PeerGroupId]
} }
@ -262,9 +261,9 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
} }
var combinedReferencedFolders = Set<PeerGroupId>() var combinedReferencedFolders = Set<PeerGroupId>()
combinedReferencedFolders.formUnion(parsedRemoteChats.referencedFolders) combinedReferencedFolders.formUnion(parsedRemoteChats.referencedFolders.keys)
if let parsedPinnedChats = parsedPinnedChats { if let parsedPinnedChats = parsedPinnedChats {
combinedReferencedFolders.formUnion(parsedPinnedChats.referencedFolders) combinedReferencedFolders.formUnion(Set(parsedPinnedChats.referencedFolders.keys))
} }
var folderSignals: [Signal<(PeerGroupId, ParsedDialogs), NoError>] = [] var folderSignals: [Signal<(PeerGroupId, ParsedDialogs), NoError>] = []
@ -316,24 +315,14 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
var peerGroupIds: [PeerId: PeerGroupId] = [:] var peerGroupIds: [PeerId: PeerGroupId] = [:]
if case let .group(groupId) = location { if case let .group(groupId) = location {
for itemId in parsedRemoteChats.itemIds { for peerId in parsedRemoteChats.itemIds {
switch itemId { peerGroupIds[peerId] = groupId
case let .peer(peerId):
peerGroupIds[peerId] = groupId
case .group:
break
}
} }
} }
for (groupId, folderChats) in folders { for (groupId, folderChats) in folders {
for itemId in folderChats.itemIds { for peerId in folderChats.itemIds {
switch itemId { peerGroupIds[peerId] = groupId
case let .peer(peerId):
peerGroupIds[peerId] = groupId
case .group:
break
}
} }
peers.append(contentsOf: folderChats.peers) peers.append(contentsOf: folderChats.peers)
peerPresences.merge(folderChats.peerPresences, uniquingKeysWith: { _, updated in updated }) peerPresences.merge(folderChats.peerPresences, uniquingKeysWith: { _, updated in updated })
@ -344,24 +333,30 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
storeMessages.append(contentsOf: folderChats.storeMessages) storeMessages.append(contentsOf: folderChats.storeMessages)
} }
var pinnedItemIds: [PinnedItemId]? var pinnedItemIds: [PeerId]?
if let parsedPinnedChats = parsedPinnedChats { if let parsedPinnedChats = parsedPinnedChats {
var array: [PinnedItemId] = [] var array: [PeerId] = []
for itemId in parsedPinnedChats.itemIds { for peerId in parsedPinnedChats.itemIds {
switch itemId { if case let .group(groupId) = location {
case let .peer(peerId): peerGroupIds[peerId] = groupId
if case let .group(groupId) = location {
peerGroupIds[peerId] = groupId
}
array.append(itemId)
case .group:
break
} }
array.append(peerId)
} }
pinnedItemIds = array pinnedItemIds = array
} }
var folderSummaries: [PeerGroupId: PeerGroupUnreadCountersSummary] = [:]
for (groupId, summary) in parsedRemoteChats.referencedFolders {
folderSummaries[groupId] = summary
}
if let parsedPinnedChats = parsedPinnedChats {
for (groupId, summary) in parsedPinnedChats.referencedFolders {
folderSummaries[groupId] = summary
}
}
return FetchedChatList( return FetchedChatList(
chatPeerIds: parsedRemoteChats.itemIds + (pinnedItemIds ?? []),
peers: peers, peers: peers,
peerPresences: peerPresences, peerPresences: peerPresences,
notificationSettings: notificationSettings, notificationSettings: notificationSettings,
@ -374,7 +369,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
lowerNonPinnedIndex: parsedRemoteChats.lowerNonPinnedIndex, lowerNonPinnedIndex: parsedRemoteChats.lowerNonPinnedIndex,
pinnedItemIds: pinnedItemIds, pinnedItemIds: pinnedItemIds,
folders: folders.map { ($0.0, $0.1.lowerNonPinnedIndex) }, folderSummaries: folderSummaries,
peerGroupIds: peerGroupIds peerGroupIds: peerGroupIds
) )
} }

View File

@ -353,12 +353,13 @@ func groupBoundaryPeer(_ peerId: PeerId, accountPeerId: PeerId) -> Api.Peer {
} }
} }
func fetchChatListHole(postbox: Postbox, network: Network, accountPeerId: PeerId, groupId: PeerGroupId?, hole: ChatListHole) -> Signal<Never, NoError> { func fetchChatListHole(postbox: Postbox, network: Network, accountPeerId: PeerId, groupId: PeerGroupId, hole: ChatListHole) -> Signal<Never, NoError> {
let location: FetchChatListLocation let location: FetchChatListLocation
if let groupId = groupId { switch groupId {
location = .group(groupId) case .root:
} else { location = .general
location = .general case .group:
location = .group(groupId)
} }
return fetchChatList(postbox: postbox, network: network, location: location, upperBound: hole.index, hash: 0, limit: 100) return fetchChatList(postbox: postbox, network: network, location: location, upperBound: hole.index, hash: 0, limit: 100)
|> mapToSignal { fetchedChats -> Signal<Never, NoError> in |> mapToSignal { fetchedChats -> Signal<Never, NoError> in
@ -381,8 +382,20 @@ func fetchChatListHole(postbox: Postbox, network: Network, accountPeerId: PeerId
transaction.replaceChatListHole(groupId: groupId, index: hole.index, hole: fetchedChats.lowerNonPinnedIndex.flatMap(ChatListHole.init)) transaction.replaceChatListHole(groupId: groupId, index: hole.index, hole: fetchedChats.lowerNonPinnedIndex.flatMap(ChatListHole.init))
for (peerId, groupId) in fetchedChats.peerGroupIds { for peerId in fetchedChats.chatPeerIds {
transaction.updatePeerGroupId(peerId, groupId: groupId) if let peer = transaction.getPeer(peerId) {
transaction.updatePeerChatListInclusion(peerId, inclusion: .ifHasMessagesOrOneOf(groupId: groupId, pinningIndex: nil, minTimestamp: minTimestampForPeerInclusion(peer)))
} else {
assertionFailure()
}
}
for (peerId, peerGroupId) in fetchedChats.peerGroupIds {
if let peer = transaction.getPeer(peerId) {
transaction.updatePeerChatListInclusion(peerId, inclusion: .ifHasMessagesOrOneOf(groupId: peerGroupId, pinningIndex: nil, minTimestamp: minTimestampForPeerInclusion(peer)))
} else {
assertionFailure()
}
} }
for (peerId, chatState) in fetchedChats.chatStates { for (peerId, chatState) in fetchedChats.chatStates {
@ -398,12 +411,16 @@ func fetchChatListHole(postbox: Postbox, network: Network, accountPeerId: PeerId
} }
if let replacePinnedItemIds = fetchedChats.pinnedItemIds { if let replacePinnedItemIds = fetchedChats.pinnedItemIds {
transaction.setPinnedItemIds(groupId: groupId, itemIds: replacePinnedItemIds) transaction.setPinnedItemIds(groupId: groupId, itemIds: replacePinnedItemIds.map(PinnedItemId.peer))
} }
for (peerId, summary) in fetchedChats.mentionTagSummaries { for (peerId, summary) in fetchedChats.mentionTagSummaries {
transaction.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: summary.count, maxId: summary.range.maxId) transaction.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: summary.count, maxId: summary.range.maxId)
} }
for (groupId, summary) in fetchedChats.folderSummaries {
transaction.resetPeerGroupSummary(groupId: groupId, namespace: Namespaces.Message.Cloud, summary: summary)
}
}) })
} }
} }

View File

@ -13,7 +13,7 @@ func managedServiceViews(accountPeerId: PeerId, network: Network, postbox: Postb
disposable.add(managedMessageHistoryHoles(accountPeerId: accountPeerId, network: network, postbox: postbox).start()) disposable.add(managedMessageHistoryHoles(accountPeerId: accountPeerId, network: network, postbox: postbox).start())
disposable.add(managedChatListHoles(network: network, postbox: postbox, accountPeerId: accountPeerId).start()) disposable.add(managedChatListHoles(network: network, postbox: postbox, accountPeerId: accountPeerId).start())
disposable.add(managedSynchronizePeerReadStates(network: network, postbox: postbox, stateManager: stateManager).start()) disposable.add(managedSynchronizePeerReadStates(network: network, postbox: postbox, stateManager: stateManager).start())
//disposable.add(managedGroupFeedReadStateSyncOperations(postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager).start()) disposable.add(managedSynchronizeGroupMessageStats(network: network, postbox: postbox, stateManager: stateManager).start())
return disposable return disposable
} }

View File

@ -0,0 +1,104 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
private final class ManagedSynchronizeGroupMessageStatsState {
private var synchronizeDisposables: [PeerGroupAndNamespace: Disposable] = [:]
func clearDisposables() -> [Disposable] {
let disposables = Array(self.synchronizeDisposables.values)
self.synchronizeDisposables.removeAll()
return disposables
}
func update(operations: Set<PeerGroupAndNamespace>) -> (removed: [Disposable], added: [(PeerGroupAndNamespace, MetaDisposable)]) {
var removed: [Disposable] = []
var added: [(PeerGroupAndNamespace, MetaDisposable)] = []
for (groupAndNamespace, disposable) in self.synchronizeDisposables {
if !operations.contains(groupAndNamespace) {
removed.append(disposable)
self.synchronizeDisposables.removeValue(forKey: groupAndNamespace)
}
}
for groupAndNamespace in operations {
if self.synchronizeDisposables[groupAndNamespace] == nil {
let disposable = MetaDisposable()
self.synchronizeDisposables[groupAndNamespace] = disposable
added.append((groupAndNamespace, disposable))
}
}
return (removed, added)
}
}
func managedSynchronizeGroupMessageStats(network: Network, postbox: Postbox, stateManager: AccountStateManager) -> Signal<Void, NoError> {
return Signal { _ in
let state = Atomic(value: ManagedSynchronizeGroupMessageStatsState())
let disposable = postbox.combinedView(keys: [.synchronizeGroupMessageStats]).start(next: { views in
let (removed, added) = state.with { state -> (removed: [Disposable], added: [(PeerGroupAndNamespace, MetaDisposable)]) in
let view = views.views[.synchronizeGroupMessageStats] as? SynchronizeGroupMessageStatsView
return state.update(operations: view?.groupsAndNamespaces ?? Set())
}
for disposable in removed {
disposable.dispose()
}
for (groupAndNamespace, disposable) in added {
let synchronizeOperation = synchronizeGroupMessageStats(postbox: postbox, network: network, groupId: groupAndNamespace.groupId, namespace: groupAndNamespace.namespace)
disposable.set(synchronizeOperation.start())
}
})
return ActionDisposable {
disposable.dispose()
for disposable in state.with({ state -> [Disposable] in
state.clearDisposables()
}) {
disposable.dispose()
}
}
}
}
private func synchronizeGroupMessageStats(postbox: Postbox, network: Network, groupId: PeerGroupId, namespace: MessageId.Namespace) -> Signal<Void, NoError> {
if namespace != Namespaces.Message.Cloud {
return postbox.transaction { transaction in
transaction.confirmSynchronizedPeerGroupMessageStats(groupId: groupId, namespace: namespace)
}
}
return network.request(Api.functions.messages.getPeerDialogs(peers: [.inputDialogPeerFolder(folderId: groupId.rawValue)]))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.messages.PeerDialogs?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.transaction { transaction in
if let result = result {
switch result {
case let .peerDialogs(peerDialogs):
for dialog in peerDialogs.dialogs {
switch dialog {
case let .dialogFolder(dialogFolder):
transaction.resetPeerGroupSummary(groupId: groupId, namespace: namespace, summary: PeerGroupUnreadCountersSummary(all: PeerGroupUnreadCounters(messageCount: dialogFolder.unreadMutedMessagesCount, chatCount: dialogFolder.unreadMutedPeersCount)))
case .dialog:
assertionFailure()
break
}
}
}
}
transaction.confirmSynchronizedPeerGroupMessageStats(groupId: groupId, namespace: namespace)
}
}
}

View File

@ -119,7 +119,7 @@ private func synchronizeGroupedPeers(transaction: Transaction, postbox: Postbox,
guard let inputPeer = transaction.getPeer(operation.peerId).flatMap(apiInputPeer) else { guard let inputPeer = transaction.getPeer(operation.peerId).flatMap(apiInputPeer) else {
return .complete() return .complete()
} }
let folderPeer: Api.InputFolderPeer = Api.InputFolderPeer.inputFolderPeer(peer: inputPeer, folderId: operation.groupId?.rawValue ?? 0) let folderPeer: Api.InputFolderPeer = Api.InputFolderPeer.inputFolderPeer(peer: inputPeer, folderId: operation.groupId.rawValue)
return network.request(Api.functions.folders.editPeerFolders(folderPeers: [folderPeer])) return network.request(Api.functions.folders.editPeerFolders(folderPeers: [folderPeer]))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in |> `catch` { _ -> Signal<Api.Updates?, NoError> in

View File

@ -86,7 +86,7 @@ func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network,
let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in
if let entry = entry { if let entry = entry {
if let operation = entry.contents as? SynchronizePinnedChatsOperation { if let operation = entry.contents as? SynchronizePinnedChatsOperation {
return synchronizePinnedChats(transaction: transaction, postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager, groupId: entry.peerId.id == 0 ? nil : PeerGroupId(rawValue: entry.peerId.id), operation: operation) return synchronizePinnedChats(transaction: transaction, postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager, groupId: PeerGroupId(rawValue: entry.peerId.id), operation: operation)
} else { } else {
assertionFailure() assertionFailure()
} }
@ -113,7 +113,7 @@ func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network,
} }
} }
private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, groupId: PeerGroupId?, operation: SynchronizePinnedChatsOperation) -> Signal<Void, NoError> { private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, groupId: PeerGroupId, operation: SynchronizePinnedChatsOperation) -> Signal<Void, NoError> {
let initialRemoteItemIds = operation.previousItemIds let initialRemoteItemIds = operation.previousItemIds
let initialRemoteItemIdsWithoutSecretChats = initialRemoteItemIds.filter { item in let initialRemoteItemIdsWithoutSecretChats = initialRemoteItemIds.filter { item in
switch item { switch item {
@ -133,7 +133,7 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
} }
} }
return network.request(Api.functions.messages.getPinnedDialogs(folderId: groupId?.rawValue ?? 0)) return network.request(Api.functions.messages.getPinnedDialogs(folderId: groupId.rawValue))
|> retryRequest |> retryRequest
|> mapToSignal { dialogs -> Signal<Void, NoError> in |> mapToSignal { dialogs -> Signal<Void, NoError> in
var storeMessages: [StoreMessage] = [] var storeMessages: [StoreMessage] = []
@ -270,21 +270,17 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) { if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
inputDialogPeers.append(Api.InputDialogPeer.inputDialogPeer(peer: inputPeer)) inputDialogPeers.append(Api.InputDialogPeer.inputDialogPeer(peer: inputPeer))
} }
case let .group(groupId):
/*feed*/
/*inputDialogPeers.append(.inputDialogPeerFeed(feedId: groupId.rawValue))*/
break
} }
} }
return network.request(Api.functions.messages.reorderPinnedDialogs(flags: 1 << 0, folderId: groupId?.rawValue ?? 0, order: inputDialogPeers)) return network.request(Api.functions.messages.reorderPinnedDialogs(flags: 1 << 0, folderId: groupId.rawValue, order: inputDialogPeers))
|> `catch` { _ -> Signal<Api.Bool, NoError> in |> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(Api.Bool.boolFalse) return .single(Api.Bool.boolFalse)
} }
|> mapToSignal { result -> Signal<Void, NoError> in |> mapToSignal { result -> Signal<Void, NoError> in
return postbox.transaction { transaction -> Void in return postbox.transaction { transaction -> Void in
}
} }
}
} }
} }
|> switchToLatest |> switchToLatest

View File

@ -37,18 +37,18 @@ public func removePeerChat(account: Account, transaction: Transaction, mediaBox:
} }
} }
clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId) clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId)
transaction.updatePeerChatListInclusion(peerId, inclusion: .never) transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue) transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue)
} else { } else {
cloudChatAddRemoveChatOperation(transaction: transaction, peerId: peerId, reportChatSpam: reportChatSpam, deleteGloballyIfPossible: deleteGloballyIfPossible) cloudChatAddRemoveChatOperation(transaction: transaction, peerId: peerId, reportChatSpam: reportChatSpam, deleteGloballyIfPossible: deleteGloballyIfPossible)
if peerId.namespace == Namespaces.Peer.CloudUser { if peerId.namespace == Namespaces.Peer.CloudUser {
transaction.updatePeerChatListInclusion(peerId, inclusion: .ifHasMessages) transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId) clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId)
} else if peerId.namespace == Namespaces.Peer.CloudGroup { } else if peerId.namespace == Namespaces.Peer.CloudGroup {
transaction.updatePeerChatListInclusion(peerId, inclusion: .never) transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId) clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId)
} else { } else {
transaction.updatePeerChatListInclusion(peerId, inclusion: .never) transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
} }
} }
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue) transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue)

View File

@ -9,53 +9,48 @@ import Foundation
final class SynchronizeGroupedPeersOperation: PostboxCoding { final class SynchronizeGroupedPeersOperation: PostboxCoding {
let peerId: PeerId let peerId: PeerId
let groupId: PeerGroupId? let groupId: PeerGroupId
init(peerId: PeerId, groupId: PeerGroupId?) { init(peerId: PeerId, groupId: PeerGroupId) {
self.peerId = peerId self.peerId = peerId
self.groupId = groupId self.groupId = groupId
} }
init(decoder: PostboxDecoder) { init(decoder: PostboxDecoder) {
self.peerId = PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)) self.peerId = PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0))
self.groupId = decoder.decodeOptionalInt32ForKey("groupId").flatMap(PeerGroupId.init(rawValue:)) self.groupId = PeerGroupId.init(rawValue: decoder.decodeInt32ForKey("groupId", orElse: 0))
} }
func encode(_ encoder: PostboxEncoder) { func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.peerId.toInt64(), forKey: "peerId") encoder.encodeInt64(self.peerId.toInt64(), forKey: "peerId")
if let groupId = self.groupId { encoder.encodeInt32(self.groupId.rawValue, forKey: "groupId")
encoder.encodeInt32(groupId.rawValue, forKey: "groupId")
} else {
encoder.encodeNil(forKey: "groupId")
}
} }
} }
public func updatePeerGroupIdInteractively(postbox: Postbox, peerId: PeerId, groupId: PeerGroupId?) -> Signal<Void, NoError> { public func updatePeerGroupIdInteractively(postbox: Postbox, peerId: PeerId, groupId: PeerGroupId) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in return postbox.transaction { transaction -> Void in
let previousGroupId = transaction.getPeerGroupId(peerId) updatePeerGroupIdInteractively(transaction: transaction, peerId: peerId, groupId: groupId)
if previousGroupId != groupId {
transaction.updatePeerGroupId(peerId, groupId: groupId)
if peerId.namespace != Namespaces.Peer.SecretChat {
addSynchronizeGroupedPeersOperation(transaction: transaction, peerId: peerId, groupId: groupId)
}
}
} }
} }
public func updatePeerGroupIdInteractively(transaction: Transaction, peerId: PeerId, groupId: PeerGroupId?) { public func updatePeerGroupIdInteractively(transaction: Transaction, peerId: PeerId, groupId: PeerGroupId) {
let previousGroupId = transaction.getPeerGroupId(peerId) let initialInclusion = transaction.getPeerChatListInclusion(peerId)
var updatedInclusion = initialInclusion
if previousGroupId != groupId { switch initialInclusion {
transaction.updatePeerGroupId(peerId, groupId: groupId) case .notIncluded:
break
case let .ifHasMessagesOrOneOf(_, pinningIndex, minTimestamp):
updatedInclusion = .ifHasMessagesOrOneOf(groupId: groupId, pinningIndex: pinningIndex, minTimestamp: minTimestamp)
}
if initialInclusion != updatedInclusion {
transaction.updatePeerChatListInclusion(peerId, inclusion: updatedInclusion)
if peerId.namespace != Namespaces.Peer.SecretChat { if peerId.namespace != Namespaces.Peer.SecretChat {
addSynchronizeGroupedPeersOperation(transaction: transaction, peerId: peerId, groupId: groupId) addSynchronizeGroupedPeersOperation(transaction: transaction, peerId: peerId, groupId: groupId)
} }
} }
} }
private func addSynchronizeGroupedPeersOperation(transaction: Transaction, peerId: PeerId, groupId: PeerGroupId?) { private func addSynchronizeGroupedPeersOperation(transaction: Transaction, peerId: PeerId, groupId: PeerGroupId) {
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeGroupedPeers let tag: PeerOperationLogTag = OperationLogTags.SynchronizeGroupedPeers
let logPeerId = PeerId(namespace: 0, id: 0) let logPeerId = PeerId(namespace: 0, id: 0)

View File

@ -16,8 +16,6 @@ private struct PreviousPeerItemId: PostboxCoding {
switch decoder.decodeInt32ForKey("_t", orElse: 0) { switch decoder.decodeInt32ForKey("_t", orElse: 0) {
case 0: case 0:
self.id = .peer(PeerId(decoder.decodeInt64ForKey("i", orElse: 0))) self.id = .peer(PeerId(decoder.decodeInt64ForKey("i", orElse: 0)))
case 1:
self.id = .group(PeerGroupId(rawValue: decoder.decodeInt32ForKey("i", orElse: 0)))
default: default:
preconditionFailure() preconditionFailure()
} }
@ -28,9 +26,6 @@ private struct PreviousPeerItemId: PostboxCoding {
case let .peer(peerId): case let .peer(peerId):
encoder.encodeInt32(0, forKey: "_t") encoder.encodeInt32(0, forKey: "_t")
encoder.encodeInt64(peerId.toInt64(), forKey: "i") encoder.encodeInt64(peerId.toInt64(), forKey: "i")
case let .group(groupId):
encoder.encodeInt32(1, forKey: "_t")
encoder.encodeInt32(groupId.rawValue, forKey: "i")
} }
} }
} }
@ -52,8 +47,8 @@ final class SynchronizePinnedChatsOperation: PostboxCoding {
} }
} }
func addSynchronizePinnedChatsOperation(transaction: Transaction, groupId: PeerGroupId?) { func addSynchronizePinnedChatsOperation(transaction: Transaction, groupId: PeerGroupId) {
let rawId: Int32 = groupId?.rawValue ?? 0 let rawId: Int32 = groupId.rawValue
var previousItemIds = transaction.getPinnedItemIds(groupId: groupId) var previousItemIds = transaction.getPinnedItemIds(groupId: groupId)
var updateLocalIndex: Int32? var updateLocalIndex: Int32?

View File

@ -12,41 +12,6 @@ public enum UserPresenceStatus: Comparable, PostboxCoding {
case lastWeek case lastWeek
case lastMonth case lastMonth
public static func ==(lhs: UserPresenceStatus, rhs: UserPresenceStatus) -> Bool {
switch lhs {
case .none:
if case .none = rhs {
return true
} else {
return false
}
case let .present(until):
if case .present(until) = rhs {
return true
} else {
return false
}
case .recently:
if case .recently = rhs {
return true
} else {
return false
}
case .lastWeek:
if case .lastWeek = rhs {
return true
} else {
return false
}
case .lastMonth:
if case .lastMonth = rhs {
return true
} else {
return false
}
}
}
public static func <(lhs: UserPresenceStatus, rhs: UserPresenceStatus) -> Bool { public static func <(lhs: UserPresenceStatus, rhs: UserPresenceStatus) -> Bool {
switch lhs { switch lhs {
case .none: case .none:

View File

@ -12,7 +12,7 @@ public enum TogglePeerChatPinnedResult {
case limitExceeded case limitExceeded
} }
public func toggleItemPinned(postbox: Postbox, groupId: PeerGroupId?, itemId: PinnedItemId) -> Signal<TogglePeerChatPinnedResult, NoError> { public func toggleItemPinned(postbox: Postbox, groupId: PeerGroupId, itemId: PinnedItemId) -> Signal<TogglePeerChatPinnedResult, NoError> {
return postbox.transaction { transaction -> TogglePeerChatPinnedResult in return postbox.transaction { transaction -> TogglePeerChatPinnedResult in
var itemIds = transaction.getPinnedItemIds(groupId: groupId) var itemIds = transaction.getPinnedItemIds(groupId: groupId)
let sameKind = itemIds.filter { item in let sameKind = itemIds.filter { item in
@ -23,12 +23,6 @@ public func toggleItemPinned(postbox: Postbox, groupId: PeerGroupId?, itemId: Pi
} else { } else {
return false return false
} }
case let .group(lhsGroupId):
if case let .group(rhsGroupId) = item {
return lhsGroupId != rhsGroupId
} else {
return false
}
} }
} }
@ -63,7 +57,7 @@ public func toggleItemPinned(postbox: Postbox, groupId: PeerGroupId?, itemId: Pi
} }
} }
public func reorderPinnedItemIds(transaction: Transaction, groupId: PeerGroupId?, itemIds: [PinnedItemId]) -> Bool { public func reorderPinnedItemIds(transaction: Transaction, groupId: PeerGroupId, itemIds: [PinnedItemId]) -> Bool {
if transaction.getPinnedItemIds(groupId: groupId) != itemIds { if transaction.getPinnedItemIds(groupId: groupId) != itemIds {
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds) transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId) addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)

View File

@ -158,80 +158,80 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId: PeerId, network
} }
} else if let _ = peer as? TelegramGroup { } else if let _ = peer as? TelegramGroup {
return network.request(Api.functions.messages.getFullChat(chatId: peerId.id)) return network.request(Api.functions.messages.getFullChat(chatId: peerId.id))
|> retryRequest |> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in |> mapToSignal { result -> Signal<Void, NoError> in
return postbox.transaction { transaction -> Void in return postbox.transaction { transaction -> Void in
switch result { switch result {
case let .chatFull(fullChat, chats, users): case let .chatFull(fullChat, chats, users):
switch fullChat { switch fullChat {
case let .chatFull(chatFull): case let .chatFull(chatFull):
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: chatFull.notifySettings)]) transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: chatFull.notifySettings)])
case .channelFull: case .channelFull:
break break
} }
switch fullChat {
case let .chatFull(chatFull):
var botInfos: [CachedPeerBotInfo] = []
for botInfo in chatFull.botInfo ?? [] {
switch botInfo {
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
}
let participants = CachedGroupParticipants(apiParticipants: chatFull.participants)
let exportedInvitation = ExportedInvitation(apiExportedInvite: chatFull.exportedInvite)
let pinnedMessageId = chatFull.pinnedMsgId.flatMap({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) })
switch fullChat { var peers: [Peer] = []
case let .chatFull(chatFull): var peerPresences: [PeerId: PeerPresence] = [:]
var botInfos: [CachedPeerBotInfo] = [] for chat in chats {
for botInfo in chatFull.botInfo ?? [] { if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
switch botInfo { peers.append(groupOrChannel)
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
} }
let participants = CachedGroupParticipants(apiParticipants: chatFull.participants) }
let exportedInvitation = ExportedInvitation(apiExportedInvite: chatFull.exportedInvite) for user in users {
let pinnedMessageId = chatFull.pinnedMsgId.flatMap({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }) let telegramUser = TelegramUser(user: user)
peers.append(telegramUser)
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
}
}
var peers: [Peer] = [] updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
var peerPresences: [PeerId: PeerPresence] = [:] return updated
for chat in chats { })
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers.append(groupOrChannel) updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences)
}
} var flags = CachedGroupFlags()
for user in users { if (chatFull.flags & 1 << 7) != 0 {
let telegramUser = TelegramUser(user: user) flags.insert(.canChangeUsername)
peers.append(telegramUser) }
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
} let previous: CachedGroupData
if let current = current as? CachedGroupData {
previous = current
} else {
previous = CachedGroupData()
} }
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in return previous.withUpdatedParticipants(participants)
return updated .withUpdatedExportedInvitation(exportedInvitation)
}) .withUpdatedBotInfos(botInfos)
.withUpdatedPinnedMessageId(pinnedMessageId)
updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences) .withUpdatedAbout(chatFull.about)
.withUpdatedFlags(flags)
var flags = CachedGroupFlags() })
if (chatFull.flags & 1 << 7) != 0 { case .channelFull:
flags.insert(.canChangeUsername) break
} }
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
let previous: CachedGroupData
if let current = current as? CachedGroupData {
previous = current
} else {
previous = CachedGroupData()
}
return previous.withUpdatedParticipants(participants)
.withUpdatedExportedInvitation(exportedInvitation)
.withUpdatedBotInfos(botInfos)
.withUpdatedPinnedMessageId(pinnedMessageId)
.withUpdatedAbout(chatFull.about)
.withUpdatedFlags(flags)
})
case .channelFull:
break
}
}
} }
} }
}
} else if let inputChannel = apiInputChannel(peer) { } else if let inputChannel = apiInputChannel(peer) {
return network.request(Api.functions.channels.getFullChannel(channel: inputChannel)) return network.request(Api.functions.channels.getFullChannel(channel: inputChannel))
|> map(Optional.init) |> map(Optional.init)
@ -254,7 +254,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId: PeerId, network
} }
switch fullChat { switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId): case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, pts):
var channelFlags = CachedChannelFlags() var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants) channelFlags.insert(.canDisplayParticipants)

View File

@ -61,7 +61,7 @@ func apiUpdatePtsRange(_ update: Api.Update) -> (Int32, Int32)? {
return (pts, ptsCount) return (pts, ptsCount)
case let .updateNewMessage(_, pts, ptsCount): case let .updateNewMessage(_, pts, ptsCount):
return (pts, ptsCount) return (pts, ptsCount)
case let .updateReadHistoryInbox(_, _, pts, ptsCount): case let .updateReadHistoryInbox(_, _, _, _, _, pts, ptsCount):
return (pts, ptsCount) return (pts, ptsCount)
case let .updateReadHistoryOutbox(_, _, pts, ptsCount): case let .updateReadHistoryOutbox(_, _, pts, ptsCount):
return (pts, ptsCount) return (pts, ptsCount)

View File

@ -9,8 +9,18 @@ func updatePeerChatInclusionWithMinTimestamp(transaction: Transaction, id: PeerI
let currentInclusion = transaction.getPeerChatListInclusion(id) let currentInclusion = transaction.getPeerChatListInclusion(id)
var updatedInclusion: PeerChatListInclusion? var updatedInclusion: PeerChatListInclusion?
switch currentInclusion { switch currentInclusion {
case .ifHasMessages, .ifHasMessagesOrOneOf: case let .ifHasMessagesOrOneOf(groupId, pinningIndex, currentMinTimestamp):
updatedInclusion = currentInclusion.withSetIfHasMessagesOrMaxMinTimestamp(minTimestamp) let updatedMinTimestamp: Int32
if let currentMinTimestamp = currentMinTimestamp {
if minTimestamp > currentMinTimestamp {
updatedMinTimestamp = minTimestamp
} else {
updatedMinTimestamp = currentMinTimestamp
}
} else {
updatedMinTimestamp = minTimestamp
}
updatedInclusion = .ifHasMessagesOrOneOf(groupId: groupId, pinningIndex: pinningIndex, minTimestamp: updatedMinTimestamp)
default: default:
break break
} }
@ -19,17 +29,13 @@ func updatePeerChatInclusionWithMinTimestamp(transaction: Transaction, id: PeerI
} }
} }
func updatePeerChatInclousionWithNewMessages(transaction: Transaction, id: PeerId) { func minTimestampForPeerInclusion(_ peer: Peer) -> Int32? {
let currentInclusion = transaction.getPeerChatListInclusion(id) if let group = peer as? TelegramGroup {
var updatedInclusion: PeerChatListInclusion? return group.creationDate
switch currentInclusion { } else if let channel = peer as? TelegramChannel {
case .notSpecified: return channel.creationDate
updatedInclusion = .ifHasMessages } else {
default: return nil
break
}
if let updatedInclusion = updatedInclusion {
transaction.updatePeerChatListInclusion(id, inclusion: updatedInclusion)
} }
} }
@ -37,31 +43,19 @@ public func updatePeers(transaction: Transaction, peers: [Peer], update: (Peer?,
transaction.updatePeersInternal(peers, update: { previous, updated in transaction.updatePeersInternal(peers, update: { previous, updated in
let peerId = updated.id let peerId = updated.id
let currentInclusion = transaction.getPeerChatListInclusion(peerId)
var updatedInclusion: PeerChatListInclusion?
switch peerId.namespace { switch peerId.namespace {
case Namespaces.Peer.CloudUser: case Namespaces.Peer.CloudUser:
if currentInclusion == .notSpecified { break
updatedInclusion = .ifHasMessages
}
case Namespaces.Peer.CloudGroup: case Namespaces.Peer.CloudGroup:
if let group = updated as? TelegramGroup { if let group = updated as? TelegramGroup {
if group.flags.contains(.deactivated) { if group.flags.contains(.deactivated) {
updatedInclusion = .never transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
} else { } else {
switch group.membership { switch group.membership {
case .Member: case .Member:
if group.creationDate != 0 { updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: peerId, minTimestamp: group.creationDate)
updatedInclusion = currentInclusion.withSetIfHasMessagesOrMaxMinTimestamp(group.creationDate)
} else {
if currentInclusion == .notSpecified {
updatedInclusion = .ifHasMessages
}
}
default: default:
if currentInclusion == .notSpecified { transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
updatedInclusion = .never
}
} }
} }
} else { } else {
@ -71,30 +65,20 @@ public func updatePeers(transaction: Transaction, peers: [Peer], update: (Peer?,
if let channel = updated as? TelegramChannel { if let channel = updated as? TelegramChannel {
switch channel.participationStatus { switch channel.participationStatus {
case .member: case .member:
if channel.creationDate != 0 { updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: peerId, minTimestamp: channel.creationDate)
updatedInclusion = currentInclusion.withSetIfHasMessagesOrMaxMinTimestamp(channel.creationDate)
} else {
if currentInclusion == .notSpecified {
updatedInclusion = .ifHasMessages
}
}
case .left: case .left:
updatedInclusion = .never transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
case .kicked where channel.creationDate == 0: case .kicked where channel.creationDate == 0:
updatedInclusion = .never transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
default: default:
if currentInclusion == .notSpecified { transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
updatedInclusion = .never
}
} }
} else { } else {
assertionFailure() assertionFailure()
} }
case Namespaces.Peer.SecretChat: case Namespaces.Peer.SecretChat:
if let secretChat = updated as? TelegramSecretChat { if let secretChat = updated as? TelegramSecretChat {
if currentInclusion == .notSpecified { updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: peerId, minTimestamp: secretChat.creationDate)
updatedInclusion = currentInclusion.withSetIfHasMessagesOrMaxMinTimestamp(secretChat.creationDate)
}
} else { } else {
assertionFailure() assertionFailure()
} }
@ -102,9 +86,7 @@ public func updatePeers(transaction: Transaction, peers: [Peer], update: (Peer?,
assertionFailure() assertionFailure()
break break
} }
if let updatedInclusion = updatedInclusion {
transaction.updatePeerChatListInclusion(peerId, inclusion: updatedInclusion)
}
return update(previous, updated) return update(previous, updated)
}) })
} }

View File

@ -290,7 +290,7 @@ extension Api.Update {
return apiMessagePeerIds(message) return apiMessagePeerIds(message)
case let .updateEditMessage(message, _, _): case let .updateEditMessage(message, _, _):
return apiMessagePeerIds(message) return apiMessagePeerIds(message)
case let .updateReadChannelInbox(channelId, _): case let .updateReadChannelInbox(_, _, channelId, _, _, _):
return [PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)] return [PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)]
case let .updateNotifySettings(peer, _): case let .updateNotifySettings(peer, _):
switch peer { switch peer {