no message

This commit is contained in:
Peter Iakovlev
2018-01-23 22:58:32 +04:00
parent 50c0158683
commit bcfea1396b
14 changed files with 268 additions and 50 deletions

View File

@@ -584,6 +584,10 @@
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */; }; D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */; };
D0F7B1EB1E045C87007EB8A5 /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; }; D0F7B1EB1E045C87007EB8A5 /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; };
D0F7B1EC1E045C87007EB8A5 /* SearchPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827BA1E00451F00071108 /* SearchPeers.swift */; }; D0F7B1EC1E045C87007EB8A5 /* SearchPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827BA1E00451F00071108 /* SearchPeers.swift */; };
D0F8C39D20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */; };
D0F8C39E20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */; };
D0F8C3A02017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */; };
D0F8C3A12017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */; };
D0FA0ABD1E76C908005BB9B7 /* TwoStepVerification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA0ABC1E76C908005BB9B7 /* TwoStepVerification.swift */; }; D0FA0ABD1E76C908005BB9B7 /* TwoStepVerification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA0ABC1E76C908005BB9B7 /* TwoStepVerification.swift */; };
D0FA35051EA6135D00E56FFA /* CacheStorageSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */; }; D0FA35051EA6135D00E56FFA /* CacheStorageSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */; };
D0FA35061EA6135D00E56FFA /* CacheStorageSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */; }; D0FA35061EA6135D00E56FFA /* CacheStorageSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */; };
@@ -939,6 +943,8 @@
D0F53BE81E784A4800117362 /* ChangeAccountPhoneNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeAccountPhoneNumber.swift; sourceTree = "<group>"; }; D0F53BE81E784A4800117362 /* ChangeAccountPhoneNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeAccountPhoneNumber.swift; sourceTree = "<group>"; };
D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditedMessageAttribute.swift; sourceTree = "<group>"; }; D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditedMessageAttribute.swift; sourceTree = "<group>"; };
D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplyMarkupMessageAttribute.swift; sourceTree = "<group>"; }; D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplyMarkupMessageAttribute.swift; sourceTree = "<group>"; };
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupFeedPeers.swift; sourceTree = "<group>"; };
D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalTelegramCoreConfiguration.swift; sourceTree = "<group>"; };
D0FA0ABC1E76C908005BB9B7 /* TwoStepVerification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerification.swift; sourceTree = "<group>"; }; D0FA0ABC1E76C908005BB9B7 /* TwoStepVerification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerification.swift; sourceTree = "<group>"; };
D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CacheStorageSettings.swift; sourceTree = "<group>"; }; D0FA35041EA6135D00E56FFA /* CacheStorageSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CacheStorageSettings.swift; sourceTree = "<group>"; };
D0FA35071EA632E400E56FFA /* CollectCacheUsageStats.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectCacheUsageStats.swift; sourceTree = "<group>"; }; D0FA35071EA632E400E56FFA /* CollectCacheUsageStats.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectCacheUsageStats.swift; sourceTree = "<group>"; };
@@ -1103,6 +1109,7 @@
D01C7F031EFC1C49008305F1 /* DeviceContact.swift */, D01C7F031EFC1C49008305F1 /* DeviceContact.swift */,
D053B3FD1F16534400E2D58A /* MonotonicTime.swift */, D053B3FD1F16534400E2D58A /* MonotonicTime.swift */,
D01C06B61FBBA269001561AB /* CanSendMessagesToPeer.swift */, D01C06B61FBBA269001561AB /* CanSendMessagesToPeer.swift */,
D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */,
); );
name = Utils; name = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1579,6 +1586,7 @@
D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */, D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */,
D02395D51F8D09A50070F5C2 /* ChannelHistoryAvailabilitySettings.swift */, D02395D51F8D09A50070F5C2 /* ChannelHistoryAvailabilitySettings.swift */,
D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */, D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */,
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */,
); );
name = Peers; name = Peers;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1930,6 +1938,7 @@
D0FA8BAD1E1FD6E2001E855B /* MemoryBufferExtensions.swift in Sources */, D0FA8BAD1E1FD6E2001E855B /* MemoryBufferExtensions.swift in Sources */,
D03B0CBF1D62234A00955575 /* Log.swift in Sources */, D03B0CBF1D62234A00955575 /* Log.swift in Sources */,
C2FD33E41E687BF1008D13D4 /* PeerPhotoUpdater.swift in Sources */, C2FD33E41E687BF1008D13D4 /* PeerPhotoUpdater.swift in Sources */,
D0F8C3A02017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */,
D01C06B71FBBA269001561AB /* CanSendMessagesToPeer.swift in Sources */, D01C06B71FBBA269001561AB /* CanSendMessagesToPeer.swift in Sources */,
D0B843B51DA7FF30005F29E1 /* NBMetadataCore.m in Sources */, D0B843B51DA7FF30005F29E1 /* NBMetadataCore.m in Sources */,
D0C26D691FE02402004ABF18 /* ManagedSynchronizeGroupedPeersOperations.swift in Sources */, D0C26D691FE02402004ABF18 /* ManagedSynchronizeGroupedPeersOperations.swift in Sources */,
@@ -2046,6 +2055,7 @@
D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */, D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */, D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
C2366C861E4F403C0097CCFF /* AddressNames.swift in Sources */, C2366C861E4F403C0097CCFF /* AddressNames.swift in Sources */,
D0F8C39D20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */,
D0B843C11DA7FF30005F29E1 /* NBPhoneMetaData.m in Sources */, D0B843C11DA7FF30005F29E1 /* NBPhoneMetaData.m in Sources */,
D0528E601E65B94E00E2FEF5 /* SingleMessageView.swift in Sources */, D0528E601E65B94E00E2FEF5 /* SingleMessageView.swift in Sources */,
D08CAA841ED8164B0000FDA8 /* Localization.swift in Sources */, D08CAA841ED8164B0000FDA8 /* Localization.swift in Sources */,
@@ -2246,6 +2256,7 @@
D001F3E91E128A1C007A8C60 /* SecretChatState.swift in Sources */, D001F3E91E128A1C007A8C60 /* SecretChatState.swift in Sources */,
D08F4A6A1E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */, D08F4A6A1E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */,
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */, D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */,
D0F8C39E20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */,
D073CE6C1DCBCF17007511FD /* TextEntitiesMessageAttribute.swift in Sources */, D073CE6C1DCBCF17007511FD /* TextEntitiesMessageAttribute.swift in Sources */,
D03C53751DAD5CA9004C17B3 /* TelegramUserPresence.swift in Sources */, D03C53751DAD5CA9004C17B3 /* TelegramUserPresence.swift in Sources */,
D05452081E7B5093006EEF19 /* LoadedStickerPack.swift in Sources */, D05452081E7B5093006EEF19 /* LoadedStickerPack.swift in Sources */,
@@ -2318,6 +2329,7 @@
D03E5E0D1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */, D03E5E0D1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */,
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */, D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
C28725431EF967E700613564 /* NotificationInfoMessageAttribute.swift in Sources */, C28725431EF967E700613564 /* NotificationInfoMessageAttribute.swift in Sources */,
D0F8C3A12017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */,
D099D7471EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift in Sources */, D099D7471EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift in Sources */,
D058E0D21E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */, D058E0D21E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */,
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */, D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,

View File

@@ -69,7 +69,6 @@ enum AccountStateMutationOperation {
case UpdateChannelState(PeerId, ChannelState) case UpdateChannelState(PeerId, ChannelState)
case UpdateNotificationSettings(AccountStateNotificationSettingsSubject, PeerNotificationSettings) case UpdateNotificationSettings(AccountStateNotificationSettingsSubject, PeerNotificationSettings)
case UpdateGlobalNotificationSettings(AccountStateGlobalNotificationSettingsSubject, MessageNotificationSettings) case UpdateGlobalNotificationSettings(AccountStateGlobalNotificationSettingsSubject, MessageNotificationSettings)
case AddHole(MessageId)
case MergeApiChats([Api.Chat]) case MergeApiChats([Api.Chat])
case UpdatePeer(PeerId, (Peer?) -> Peer?) case UpdatePeer(PeerId, (Peer?) -> Peer?)
case UpdateCachedPeerData(PeerId, (CachedPeerData?) -> CachedPeerData?) case UpdateCachedPeerData(PeerId, (CachedPeerData?) -> CachedPeerData?)
@@ -102,6 +101,7 @@ struct AccountMutableState {
var peerNotificationSettings: [PeerId: PeerNotificationSettings] var peerNotificationSettings: [PeerId: PeerNotificationSettings]
var storedMessages: Set<MessageId> var storedMessages: Set<MessageId>
var readInboxMaxIds: [PeerId: MessageId] var readInboxMaxIds: [PeerId: MessageId]
var namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>]
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>] var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
@@ -119,9 +119,10 @@ struct AccountMutableState {
self.peerNotificationSettings = initialState.peerNotificationSettings self.peerNotificationSettings = initialState.peerNotificationSettings
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.branchOperationIndex = 0 self.branchOperationIndex = 0
self.namespacesWithHolesFromPreviousState = [:]
} }
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], branchOperationIndex: Int) { init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], branchOperationIndex: Int) {
self.initialState = initialState self.initialState = initialState
self.operations = operations self.operations = operations
self.state = state self.state = state
@@ -131,11 +132,12 @@ struct AccountMutableState {
self.peerNotificationSettings = peerNotificationSettings self.peerNotificationSettings = peerNotificationSettings
self.readInboxMaxIds = readInboxMaxIds self.readInboxMaxIds = readInboxMaxIds
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.namespacesWithHolesFromPreviousState = namespacesWithHolesFromPreviousState
self.branchOperationIndex = branchOperationIndex self.branchOperationIndex = branchOperationIndex
} }
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, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, branchOperationIndex: self.operations.count) return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerNotificationSettings: self.peerNotificationSettings, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, branchOperationIndex: self.operations.count)
} }
mutating func merge(_ other: AccountMutableState) { mutating func merge(_ other: AccountMutableState) {
@@ -146,6 +148,14 @@ struct AccountMutableState {
self.peers[peer.id] = peer self.peers[peer.id] = peer
} }
self.preCachedResources.append(contentsOf: other.preCachedResources) self.preCachedResources.append(contentsOf: other.preCachedResources)
for (peerId, namespaces) in other.namespacesWithHolesFromPreviousState {
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
self.self.namespacesWithHolesFromPreviousState[peerId] = Set()
}
for namespace in namespaces {
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
}
}
} }
mutating func addPreCachedResource(_ resource: MediaResource, data: Data) { mutating func addPreCachedResource(_ resource: MediaResource, data: Data) {
@@ -208,8 +218,11 @@ struct AccountMutableState {
self.addOperation(.UpdateGlobalNotificationSettings(subject, notificationSettings)) self.addOperation(.UpdateGlobalNotificationSettings(subject, notificationSettings))
} }
mutating func addHole(_ messageId: MessageId) { mutating func setNeedsHoleFromPreviousState(peerId: PeerId, namespace: MessageId.Namespace) {
self.addOperation(.AddHole(messageId)) if self.namespacesWithHolesFromPreviousState[peerId] == nil {
self.namespacesWithHolesFromPreviousState[peerId] = Set()
}
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
} }
mutating func mergeChats(_ chats: [Api.Chat]) { mutating func mergeChats(_ chats: [Api.Chat]) {
@@ -302,7 +315,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { switch operation {
case .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage:
break break
case let .AddMessages(messages, _): case let .AddMessages(messages, _):
for message in messages { for message in messages {

View File

@@ -1413,8 +1413,8 @@ private func resetChannels(_ account: Account, peers: [Peer], state: AccountMuta
updatedState.mergeUsers(dialogsUsers) updatedState.mergeUsers(dialogsUsers)
for message in storeMessages { for message in storeMessages {
if case let .Id(id) = message.id { if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
updatedState.addHole(MessageId(peerId: id.peerId, namespace: Namespaces.Message.Cloud, id: Int32.max)) updatedState.setNeedsHoleFromPreviousState(peerId: id.peerId, namespace: id.namespace)
} }
} }
@@ -1576,7 +1576,7 @@ private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableSt
updatedState.mergeChats(chats) updatedState.mergeChats(chats)
updatedState.mergeUsers(users) updatedState.mergeUsers(users)
updatedState.addHole(MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32.max)) updatedState.setNeedsHoleFromPreviousState(peerId: peer.id, namespace: Namespaces.Message.Cloud)
for apiMessage in messages { for apiMessage in messages {
if let message = StoreMessage(apiMessage: apiMessage) { if let message = StoreMessage(apiMessage: apiMessage) {
@@ -1703,7 +1703,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 .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .UpdateLangPack, .UpdateMinAvailableMessage:
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))
} }
@@ -1757,6 +1757,36 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
var langPackDifferences: [Api.LangPackDifference] = [] var langPackDifferences: [Api.LangPackDifference] = []
var pollLangPack = false var pollLangPack = false
var addHolesToGroupFeedIds = Set<PeerGroupId>()
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
for namespace in namespaces {
modifier.addHole(MessageId(peerId: peerId, namespace: namespace, id: Int32.max))
if namespace == Namespaces.Message.Cloud {
let peer: Peer? = finalState.state.peers[peerId] ?? modifier.getPeer(peerId)
if let peer = peer {
var groupId: PeerGroupId?
if let channel = peer as? TelegramChannel {
groupId = channel.peerGroupId
}
if groupId == nil {
groupId = modifier.getPeerGroupId(peerId)
}
if let groupId = groupId {
addHolesToGroupFeedIds.insert(groupId)
}
} else {
assertionFailure()
}
}
}
}
for groupId in addHolesToGroupFeedIds {
modifier.addFeedHoleFromLatestEntries(groupId: groupId)
}
for operation in optimizedOperations(finalState.state.operations) { for operation in optimizedOperations(finalState.state.operations) {
switch operation { switch operation {
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
@@ -1847,8 +1877,6 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
}) })
}) })
} }
case let .AddHole(messageId):
modifier.addHole(messageId)
case let .MergeApiChats(chats): case let .MergeApiChats(chats):
var peers: [Peer] = [] var peers: [Peer] = []
for chat in chats { for chat in chats {

View File

@@ -7,6 +7,7 @@
#endif #endif
public struct ChannelAdminEventLogEntry: Comparable { public struct ChannelAdminEventLogEntry: Comparable {
public let stableId: UInt32
public let event: AdminLogEvent public let event: AdminLogEvent
public let peers: [PeerId: Peer] public let peers: [PeerId: Peer]
@@ -25,6 +26,60 @@ public enum ChannelAdminEventLogUpdateType {
case load case load
} }
public struct ChannelAdminEventLogFilter: Equatable {
public let query: String?
public let events: AdminLogEventsFlags
public let adminPeerIds: [PeerId]?
public init(query: String? = nil, events: AdminLogEventsFlags = .all, adminPeerIds: [PeerId]? = nil) {
self.query = query
self.events = events
self.adminPeerIds = adminPeerIds
}
public static func ==(lhs: ChannelAdminEventLogFilter, rhs: ChannelAdminEventLogFilter) -> Bool {
if lhs.query != rhs.query {
return false
}
if lhs.events != rhs.events {
return false
}
if let lhsAdminPeerIds = lhs.adminPeerIds, let rhsAdminPeerIds = rhs.adminPeerIds {
if lhsAdminPeerIds != rhsAdminPeerIds {
return false
}
} else if (lhs.adminPeerIds != nil) != (rhs.adminPeerIds != nil) {
return false
}
return true
}
public var isEmpty: Bool {
if self.query != nil {
return false
}
if self.events != .all {
return false
}
if self.adminPeerIds != nil {
return false
}
return true
}
public func withQuery(_ query: String?) -> ChannelAdminEventLogFilter {
return ChannelAdminEventLogFilter(query: query, events: self.events, adminPeerIds: self.adminPeerIds)
}
public func withEvents(_ events: AdminLogEventsFlags) -> ChannelAdminEventLogFilter {
return ChannelAdminEventLogFilter(query: self.query, events: events, adminPeerIds: self.adminPeerIds)
}
public func withAdminPeerIds(_ adminPeerIds: [PeerId]?) -> ChannelAdminEventLogFilter {
return ChannelAdminEventLogFilter(query: self.query, events: self.events, adminPeerIds: adminPeerIds)
}
}
public final class ChannelAdminEventLogContext { public final class ChannelAdminEventLogContext {
private let queue: Queue = Queue.mainQueue() private let queue: Queue = Queue.mainQueue()
@@ -32,7 +87,12 @@ public final class ChannelAdminEventLogContext {
private let network: Network private let network: Network
private let peerId: PeerId private let peerId: PeerId
private var entries: [ChannelAdminEventLogEntry] = [] private var filter: ChannelAdminEventLogFilter = ChannelAdminEventLogFilter()
private var nextStableId: UInt32 = 1
private var stableIds: [AdminLogEventId: UInt32] = [:]
private var entries: ([ChannelAdminEventLogEntry], ChannelAdminEventLogFilter) = ([], ChannelAdminEventLogFilter())
private var hasEarlier: Bool = true private var hasEarlier: Bool = true
private var loadingMoreEarlier: Bool = false private var loadingMoreEarlier: Bool = false
@@ -54,10 +114,10 @@ public final class ChannelAdminEventLogContext {
let queue = self.queue let queue = self.queue
return Signal { [weak self] subscriber in return Signal { [weak self] subscriber in
if let strongSelf = self { if let strongSelf = self {
subscriber.putNext((strongSelf.entries, strongSelf.hasEarlier, .initial)) subscriber.putNext((strongSelf.entries.0, strongSelf.hasEarlier, .initial))
let index = strongSelf.subscribers.add({ entries, hasEarlier, type in let index = strongSelf.subscribers.add({ entries, hasEarlier, type in
subscriber.putNext((strongSelf.entries, strongSelf.hasEarlier, type)) subscriber.putNext((strongSelf.entries.0, strongSelf.hasEarlier, type))
}) })
return ActionDisposable { return ActionDisposable {
@@ -73,6 +133,20 @@ public final class ChannelAdminEventLogContext {
} |> runOn(queue) } |> runOn(queue)
} }
public func setFilter(_ filter: ChannelAdminEventLogFilter) {
if self.filter != filter {
self.filter = filter
self.loadingMoreEarlier = false
self.hasEarlier = false
for subscriber in self.subscribers.copyItems() {
subscriber(self.entries.0, self.hasEarlier, .load)
}
self.loadMoreEntries()
}
}
public func loadMoreEntries() { public func loadMoreEntries() {
assert(self.queue.isCurrent()) assert(self.queue.isCurrent())
@@ -81,18 +155,19 @@ public final class ChannelAdminEventLogContext {
} }
let maxId: AdminLogEventId let maxId: AdminLogEventId
if let last = self.entries.last { if self.entries.1 == self.filter, let first = self.entries.0.first {
maxId = last.event.id maxId = first.event.id
} else { } else {
maxId = AdminLogEventId.max maxId = AdminLogEventId.max
} }
self.loadingMoreEarlier = true self.loadingMoreEarlier = true
self.loadMoreDisposable.set((channelAdminLogEvents(postbox: self.postbox, network: self.network, peerId: self.peerId, maxId: maxId, minId: AdminLogEventId.min, limit: 10, query: nil, filter: nil, admins: nil) self.loadMoreDisposable.set((channelAdminLogEvents(postbox: self.postbox, network: self.network, peerId: self.peerId, maxId: maxId, minId: AdminLogEventId.min, limit: 100, query: self.filter.query, filter: self.filter.events, admins: self.filter.adminPeerIds)
|> deliverOn(self.queue)).start(next: { [weak self] result in |> deliverOn(self.queue)).start(next: { [weak self] result in
if let strongSelf = self { if let strongSelf = self {
var events = result.events.sorted() var events = result.events.sorted()
if let first = strongSelf.entries.first { if strongSelf.entries.1 == strongSelf.filter {
if let first = strongSelf.entries.0.first {
var clipIndex = events.count var clipIndex = events.count
for i in (0 ..< events.count).reversed() { for i in (0 ..< events.count).reversed() {
if events[i] >= first.event { if events[i] >= first.event {
@@ -104,21 +179,36 @@ public final class ChannelAdminEventLogContext {
} }
} }
strongSelf.hasEarlier = !events.isEmpty
var entries: [ChannelAdminEventLogEntry] = events.map { event in var entries: [ChannelAdminEventLogEntry] = events.map { event in
return ChannelAdminEventLogEntry(event: event, peers: result.peers) return ChannelAdminEventLogEntry(stableId: strongSelf.stableIdForEventId(event.id), event: event, peers: result.peers)
}
entries.append(contentsOf: strongSelf.entries.0)
strongSelf.entries = (entries, strongSelf.filter)
} else {
let entries: [ChannelAdminEventLogEntry] = events.map { event in
return ChannelAdminEventLogEntry(stableId: strongSelf.stableIdForEventId(event.id), event: event, peers: result.peers)
}
strongSelf.entries = (entries, strongSelf.filter)
} }
entries.append(contentsOf: strongSelf.entries)
strongSelf.entries = entries
strongSelf.hasEarlier = !events.isEmpty
strongSelf.loadingMoreEarlier = false strongSelf.loadingMoreEarlier = false
for subscriber in strongSelf.subscribers.copyItems() { for subscriber in strongSelf.subscribers.copyItems() {
subscriber(strongSelf.entries, strongSelf.hasEarlier, .load) subscriber(strongSelf.entries.0, strongSelf.hasEarlier, .load)
} }
} }
})) }))
} }
private func stableIdForEventId(_ id: AdminLogEventId) -> UInt32 {
if let value = self.stableIds[id] {
return value
} else {
let value = self.nextStableId
self.nextStableId += 1
self.stableIds[id] = value
return value
}
}
} }

View File

@@ -81,7 +81,7 @@ public struct AdminLogEventsFlags : OptionSet {
public static let editMessages = AdminLogEventsFlags(rawValue: 1 << 12) public static let editMessages = AdminLogEventsFlags(rawValue: 1 << 12)
public static let deleteMessages = AdminLogEventsFlags(rawValue: 1 << 13) public static let deleteMessages = AdminLogEventsFlags(rawValue: 1 << 13)
public static var all: [AdminLogEventsFlags] { public static var all: AdminLogEventsFlags {
return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages] return [.join, .leave, .invite, .ban, .unban, .kick, .unkick, .promote, .demote, .info, .settings, .pinnedMessages, .editMessages, .deleteMessages]
} }
public static var flags: AdminLogEventsFlags { public static var flags: AdminLogEventsFlags {

View File

@@ -0,0 +1,5 @@
import Foundation
public final class GlobalTelegramCoreConfiguration {
public static var readMessages: Bool = true
}

View File

@@ -0,0 +1,50 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
public func availableGroupFeedPeers(postbox: Postbox, network: Network, groupId: PeerGroupId) -> Signal<[(Peer, Bool)], NoError> {
return network.request(Api.functions.channels.getFeedSources(flags: 0, feedId: groupId.rawValue, hash: 0))
|> retryRequest
|> mapToSignal { result -> Signal<[(Peer, Bool)], NoError> in
return postbox.modify { modifier -> [(Peer, Bool)] in
switch result {
case .feedSourcesNotModified:
return []
case let .feedSources(_, newlyJoinedFeed, feeds, chats, users):
var includedPeerIds = Set<PeerId>()
var excludedPeerIds = Set<PeerId>()
for feedsInfo in feeds {
switch feedsInfo {
case let .feedBroadcasts(feedId, channels):
if feedId == groupId.rawValue {
for id in channels {
includedPeerIds.insert(PeerId(namespace: Namespaces.Peer.CloudChannel, id: id))
}
}
case let .feedBroadcastsUngrouped(channels):
for id in channels {
excludedPeerIds.insert(PeerId(namespace: Namespaces.Peer.CloudChannel, id: id))
}
}
}
var peers: [(Peer, Bool)] = []
for peerId in includedPeerIds {
if let peer = modifier.getPeer(peerId) {
peers.append((peer, true))
}
}
for peerId in excludedPeerIds {
if let peer = modifier.getPeer(peerId) {
peers.append((peer, false))
}
}
return peers
}
}
}
}

View File

@@ -171,9 +171,13 @@ private func groupBoundaryPeer(_ peerId: PeerId, accountPeerId: PeerId) -> Api.P
private func pushReadState(network: Network, accountPeerId: PeerId, groupId: PeerGroupId, state: GroupFeedReadState) -> Signal<Api.Updates?, NoError> { private func pushReadState(network: Network, accountPeerId: PeerId, groupId: PeerGroupId, state: GroupFeedReadState) -> Signal<Api.Updates?, NoError> {
let position: Api.FeedPosition = .feedPosition(date: state.maxReadIndex.timestamp, peer: groupBoundaryPeer(state.maxReadIndex.id.peerId, accountPeerId: accountPeerId), id: state.maxReadIndex.id.id) let position: Api.FeedPosition = .feedPosition(date: state.maxReadIndex.timestamp, peer: groupBoundaryPeer(state.maxReadIndex.id.peerId, accountPeerId: accountPeerId), id: state.maxReadIndex.id.id)
if GlobalTelegramCoreConfiguration.readMessages {
return network.request(Api.functions.channels.readFeed(feedId: groupId.rawValue, maxPosition: position)) return network.request(Api.functions.channels.readFeed(feedId: groupId.rawValue, maxPosition: position))
|> retryRequest |> retryRequest
|> map(Optional.init) |> map(Optional.init)
} else {
return .single(nil)
}
} }
private func performSyncOperation(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, groupId: PeerGroupId, operation: GroupFeedReadStateSyncOperation) -> Signal<Void, NoError> { private func performSyncOperation(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, groupId: PeerGroupId, operation: GroupFeedReadStateSyncOperation) -> Signal<Void, NoError> {

View File

@@ -202,7 +202,7 @@ public enum UpdatePeerAdminRightsError {
case addMemberError(AddPeerMemberError) case addMemberError(AddPeerMemberError)
} }
func fetchChannelParticipant(account: Account, peerId: PeerId, participantId: PeerId) -> Signal<ChannelParticipant?, NoError> { public func fetchChannelParticipant(account: Account, peerId: PeerId, participantId: PeerId) -> Signal<ChannelParticipant?, NoError> {
return account.postbox.modify { modifier -> Signal<ChannelParticipant?, NoError> in return account.postbox.modify { modifier -> Signal<ChannelParticipant?, NoError> in
if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(participantId), let inputUser = apiInputUser(adminPeer) { if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(participantId), let inputUser = apiInputUser(adminPeer) {
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) { if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {

View File

@@ -64,7 +64,7 @@ public enum ResolvePeerByNameOptionRemote {
public func resolvePeerByName(account: Account, name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<PeerId?, NoError> { public func resolvePeerByName(account: Account, name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<PeerId?, NoError> {
var normalizedName = name var normalizedName = name
if normalizedName.hasPrefix("@") { if normalizedName.hasPrefix("@") {
normalizedName = normalizedName.substring(from: name.index(after: name.startIndex)) normalizedName = String(normalizedName[name.index(after: name.startIndex)...])
} }
return account.postbox.modify { modifier -> CachedResolvedByNamePeer? in return account.postbox.modify { modifier -> CachedResolvedByNamePeer? in
@@ -82,7 +82,6 @@ public func resolvePeerByName(account: Account, name: String, ageLimit: Int32 =
return account.postbox.modify { modifier -> PeerId? in return account.postbox.modify { modifier -> PeerId? in
var peerId: PeerId? = nil var peerId: PeerId? = nil
//contacts.resolvedPeer peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;
switch result { switch result {
case let .resolvedPeer(apiPeer, chats, users): case let .resolvedPeer(apiPeer, chats, users):
var peers: [PeerId: Peer] = [:] var peers: [PeerId: Peer] = [:]

View File

@@ -55,6 +55,18 @@ public func updatePeerGroupIdInteractively(postbox: Postbox, peerId: PeerId, gro
} }
} }
public func clearPeerGroupInteractively(postbox: Postbox, groupId: PeerGroupId) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Void in
var previousGroupPeerIds = Set<PeerId>()
previousGroupPeerIds = modifier.getPeerIdsInGroup(groupId)
for peerId in modifier.getPeerIdsInGroup(groupId) {
modifier.updatePeerGroupId(peerId, groupId: nil)
}
addSynchronizeGroupedPeersOperation(modifier: modifier, groupId: groupId, initialPeerIds: previousGroupPeerIds)
}
}
private func addSynchronizeGroupedPeersOperation(modifier: Modifier, groupId: PeerGroupId, initialPeerIds: Set<PeerId>) { private func addSynchronizeGroupedPeersOperation(modifier: Modifier, groupId: PeerGroupId, initialPeerIds: Set<PeerId>) {
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeGroupedPeers let tag: PeerOperationLogTag = OperationLogTags.SynchronizeGroupedPeers
let peerId = PeerId(namespace: 0, id: groupId.rawValue) let peerId = PeerId(namespace: 0, id: groupId.rawValue)

View File

@@ -235,9 +235,9 @@ private func validatePeerReadState(network: Network, postbox: Postbox, stateMana
} }
private func pushPeerReadState(network: Network, postbox: Postbox, stateManager: AccountStateManager, peerId: PeerId, readState: PeerReadState) -> Signal<PeerReadState, VerifyReadStateError> { private func pushPeerReadState(network: Network, postbox: Postbox, stateManager: AccountStateManager, peerId: PeerId, readState: PeerReadState) -> Signal<PeerReadState, VerifyReadStateError> {
#if (arch(i386) || arch(x86_64)) && os(iOS) if !GlobalTelegramCoreConfiguration.readMessages {
//return .single(readState) return .single(readState)
#endif }
if peerId.namespace == Namespaces.Peer.SecretChat { if peerId.namespace == Namespaces.Peer.SecretChat {
return inputSecretChat(postbox: postbox, peerId: peerId) return inputSecretChat(postbox: postbox, peerId: peerId)

View File

@@ -78,6 +78,10 @@ public struct TelegramChannelGroupFlags: OptionSet {
public struct TelegramChannelGroupInfo: Equatable { public struct TelegramChannelGroupInfo: Equatable {
public let flags: TelegramChannelGroupFlags public let flags: TelegramChannelGroupFlags
public init(flags: TelegramChannelGroupFlags) {
self.flags = flags
}
public static func ==(lhs: TelegramChannelGroupInfo, rhs: TelegramChannelGroupInfo) -> Bool { public static func ==(lhs: TelegramChannelGroupInfo, rhs: TelegramChannelGroupInfo) -> Bool {
return lhs.flags == rhs.flags return lhs.flags == rhs.flags
} }

View File

@@ -29,7 +29,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case gameScore(gameId: Int64, score: Int32) case gameScore(gameId: Int64, score: Int32)
case phoneCall(callId: Int64, discardReason: PhoneCallDiscardReason?, duration: Int32?) case phoneCall(callId: Int64, discardReason: PhoneCallDiscardReason?, duration: Int32?)
case paymentSent(currency: String, totalAmount: Int64) case paymentSent(currency: String, totalAmount: Int64)
case customText(text: String) case customText(text: String, entities: [MessageTextEntity])
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0) let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
@@ -69,7 +69,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case 15: case 15:
self = .paymentSent(currency: decoder.decodeStringForKey("currency", orElse: ""), totalAmount: decoder.decodeInt64ForKey("ta", orElse: 0)) self = .paymentSent(currency: decoder.decodeStringForKey("currency", orElse: ""), totalAmount: decoder.decodeInt64ForKey("ta", orElse: 0))
case 16: case 16:
self = .customText(text: decoder.decodeStringForKey("text", orElse: "")) self = .customText(text: decoder.decodeStringForKey("text", orElse: ""), entities: decoder.decodeObjectArrayWithDecoderForKey("ent"))
default: default:
self = .unknown self = .unknown
} }
@@ -140,9 +140,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
} else { } else {
encoder.encodeNil(forKey: "d") encoder.encodeNil(forKey: "d")
} }
case let .customText(text): case let .customText(text, entities):
encoder.encodeInt32(16, forKey: "_rawValue") encoder.encodeInt32(16, forKey: "_rawValue")
encoder.encodeString(text, forKey: "text") encoder.encodeString(text, forKey: "text")
encoder.encodeObjectArray(entities, forKey: "ent")
} }
} }
@@ -262,8 +263,8 @@ public func ==(lhs: TelegramMediaActionType, rhs: TelegramMediaActionType) -> Bo
} else { } else {
return false return false
} }
case let .customText(text): case let .customText(lhsText, lhsEntities):
if case .customText(text) = rhs { if case let .customText(rhsText, rhsEntities) = rhs, lhsText == rhsText, lhsEntities == rhsEntities {
return true return true
} else { } else {
return false return false
@@ -343,7 +344,7 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
case .messageActionScreenshotTaken: case .messageActionScreenshotTaken:
return TelegramMediaAction(action: .historyScreenshot) return TelegramMediaAction(action: .historyScreenshot)
case let .messageActionCustomAction(message): case let .messageActionCustomAction(message):
return TelegramMediaAction(action: .customText(text: message)) return TelegramMediaAction(action: .customText(text: message, entities: []))
} }
} }