mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
no message
This commit is contained in:
@@ -584,6 +584,10 @@
|
||||
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */; };
|
||||
D0F7B1EB1E045C87007EB8A5 /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.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 */; };
|
||||
D0FA35051EA6135D00E56FFA /* 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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@@ -1103,6 +1109,7 @@
|
||||
D01C7F031EFC1C49008305F1 /* DeviceContact.swift */,
|
||||
D053B3FD1F16534400E2D58A /* MonotonicTime.swift */,
|
||||
D01C06B61FBBA269001561AB /* CanSendMessagesToPeer.swift */,
|
||||
D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
@@ -1579,6 +1586,7 @@
|
||||
D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */,
|
||||
D02395D51F8D09A50070F5C2 /* ChannelHistoryAvailabilitySettings.swift */,
|
||||
D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */,
|
||||
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */,
|
||||
);
|
||||
name = Peers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1930,6 +1938,7 @@
|
||||
D0FA8BAD1E1FD6E2001E855B /* MemoryBufferExtensions.swift in Sources */,
|
||||
D03B0CBF1D62234A00955575 /* Log.swift in Sources */,
|
||||
C2FD33E41E687BF1008D13D4 /* PeerPhotoUpdater.swift in Sources */,
|
||||
D0F8C3A02017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */,
|
||||
D01C06B71FBBA269001561AB /* CanSendMessagesToPeer.swift in Sources */,
|
||||
D0B843B51DA7FF30005F29E1 /* NBMetadataCore.m in Sources */,
|
||||
D0C26D691FE02402004ABF18 /* ManagedSynchronizeGroupedPeersOperations.swift in Sources */,
|
||||
@@ -2046,6 +2055,7 @@
|
||||
D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
|
||||
D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
|
||||
C2366C861E4F403C0097CCFF /* AddressNames.swift in Sources */,
|
||||
D0F8C39D20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */,
|
||||
D0B843C11DA7FF30005F29E1 /* NBPhoneMetaData.m in Sources */,
|
||||
D0528E601E65B94E00E2FEF5 /* SingleMessageView.swift in Sources */,
|
||||
D08CAA841ED8164B0000FDA8 /* Localization.swift in Sources */,
|
||||
@@ -2246,6 +2256,7 @@
|
||||
D001F3E91E128A1C007A8C60 /* SecretChatState.swift in Sources */,
|
||||
D08F4A6A1E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */,
|
||||
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */,
|
||||
D0F8C39E20178B9B00236FC5 /* GroupFeedPeers.swift in Sources */,
|
||||
D073CE6C1DCBCF17007511FD /* TextEntitiesMessageAttribute.swift in Sources */,
|
||||
D03C53751DAD5CA9004C17B3 /* TelegramUserPresence.swift in Sources */,
|
||||
D05452081E7B5093006EEF19 /* LoadedStickerPack.swift in Sources */,
|
||||
@@ -2318,6 +2329,7 @@
|
||||
D03E5E0D1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */,
|
||||
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
|
||||
C28725431EF967E700613564 /* NotificationInfoMessageAttribute.swift in Sources */,
|
||||
D0F8C3A12017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift in Sources */,
|
||||
D099D7471EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift in Sources */,
|
||||
D058E0D21E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */,
|
||||
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,
|
||||
|
||||
@@ -69,7 +69,6 @@ enum AccountStateMutationOperation {
|
||||
case UpdateChannelState(PeerId, ChannelState)
|
||||
case UpdateNotificationSettings(AccountStateNotificationSettingsSubject, PeerNotificationSettings)
|
||||
case UpdateGlobalNotificationSettings(AccountStateGlobalNotificationSettingsSubject, MessageNotificationSettings)
|
||||
case AddHole(MessageId)
|
||||
case MergeApiChats([Api.Chat])
|
||||
case UpdatePeer(PeerId, (Peer?) -> Peer?)
|
||||
case UpdateCachedPeerData(PeerId, (CachedPeerData?) -> CachedPeerData?)
|
||||
@@ -102,6 +101,7 @@ struct AccountMutableState {
|
||||
var peerNotificationSettings: [PeerId: PeerNotificationSettings]
|
||||
var storedMessages: Set<MessageId>
|
||||
var readInboxMaxIds: [PeerId: MessageId]
|
||||
var namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>]
|
||||
|
||||
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
|
||||
|
||||
@@ -119,9 +119,10 @@ struct AccountMutableState {
|
||||
self.peerNotificationSettings = initialState.peerNotificationSettings
|
||||
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
|
||||
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.operations = operations
|
||||
self.state = state
|
||||
@@ -131,11 +132,12 @@ struct AccountMutableState {
|
||||
self.peerNotificationSettings = peerNotificationSettings
|
||||
self.readInboxMaxIds = readInboxMaxIds
|
||||
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
|
||||
self.namespacesWithHolesFromPreviousState = namespacesWithHolesFromPreviousState
|
||||
self.branchOperationIndex = branchOperationIndex
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -146,6 +148,14 @@ struct AccountMutableState {
|
||||
self.peers[peer.id] = peer
|
||||
}
|
||||
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) {
|
||||
@@ -208,8 +218,11 @@ struct AccountMutableState {
|
||||
self.addOperation(.UpdateGlobalNotificationSettings(subject, notificationSettings))
|
||||
}
|
||||
|
||||
mutating func addHole(_ messageId: MessageId) {
|
||||
self.addOperation(.AddHole(messageId))
|
||||
mutating func setNeedsHoleFromPreviousState(peerId: PeerId, namespace: MessageId.Namespace) {
|
||||
if self.namespacesWithHolesFromPreviousState[peerId] == nil {
|
||||
self.namespacesWithHolesFromPreviousState[peerId] = Set()
|
||||
}
|
||||
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
|
||||
}
|
||||
|
||||
mutating func mergeChats(_ chats: [Api.Chat]) {
|
||||
@@ -302,7 +315,7 @@ struct AccountMutableState {
|
||||
|
||||
mutating func addOperation(_ operation: AccountStateMutationOperation) {
|
||||
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
|
||||
case let .AddMessages(messages, _):
|
||||
for message in messages {
|
||||
|
||||
@@ -1413,8 +1413,8 @@ private func resetChannels(_ account: Account, peers: [Peer], state: AccountMuta
|
||||
updatedState.mergeUsers(dialogsUsers)
|
||||
|
||||
for message in storeMessages {
|
||||
if case let .Id(id) = message.id {
|
||||
updatedState.addHole(MessageId(peerId: id.peerId, namespace: Namespaces.Message.Cloud, id: Int32.max))
|
||||
if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
|
||||
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.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 {
|
||||
if let message = StoreMessage(apiMessage: apiMessage) {
|
||||
@@ -1703,7 +1703,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
|
||||
var currentAddMessages: OptimizeAddMessagesState?
|
||||
for operation in operations {
|
||||
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 {
|
||||
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
|
||||
}
|
||||
@@ -1757,6 +1757,36 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
|
||||
var langPackDifferences: [Api.LangPackDifference] = []
|
||||
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) {
|
||||
switch operation {
|
||||
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):
|
||||
var peers: [Peer] = []
|
||||
for chat in chats {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#endif
|
||||
|
||||
public struct ChannelAdminEventLogEntry: Comparable {
|
||||
public let stableId: UInt32
|
||||
public let event: AdminLogEvent
|
||||
public let peers: [PeerId: Peer]
|
||||
|
||||
@@ -25,6 +26,60 @@ public enum ChannelAdminEventLogUpdateType {
|
||||
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 {
|
||||
private let queue: Queue = Queue.mainQueue()
|
||||
|
||||
@@ -32,7 +87,12 @@ public final class ChannelAdminEventLogContext {
|
||||
private let network: Network
|
||||
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 loadingMoreEarlier: Bool = false
|
||||
|
||||
@@ -54,10 +114,10 @@ public final class ChannelAdminEventLogContext {
|
||||
let queue = self.queue
|
||||
return Signal { [weak self] subscriber in
|
||||
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
|
||||
subscriber.putNext((strongSelf.entries, strongSelf.hasEarlier, type))
|
||||
subscriber.putNext((strongSelf.entries.0, strongSelf.hasEarlier, type))
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
@@ -73,6 +133,20 @@ public final class ChannelAdminEventLogContext {
|
||||
} |> 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() {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
@@ -81,18 +155,19 @@ public final class ChannelAdminEventLogContext {
|
||||
}
|
||||
|
||||
let maxId: AdminLogEventId
|
||||
if let last = self.entries.last {
|
||||
maxId = last.event.id
|
||||
if self.entries.1 == self.filter, let first = self.entries.0.first {
|
||||
maxId = first.event.id
|
||||
} else {
|
||||
maxId = AdminLogEventId.max
|
||||
}
|
||||
|
||||
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
|
||||
if let strongSelf = self {
|
||||
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
|
||||
for i in (0 ..< events.count).reversed() {
|
||||
if events[i] >= first.event {
|
||||
@@ -104,21 +179,36 @@ public final class ChannelAdminEventLogContext {
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.hasEarlier = !events.isEmpty
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public struct AdminLogEventsFlags : OptionSet {
|
||||
public static let editMessages = AdminLogEventsFlags(rawValue: 1 << 12)
|
||||
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]
|
||||
}
|
||||
public static var flags: AdminLogEventsFlags {
|
||||
|
||||
5
TelegramCore/GlobalTelegramCoreConfiguration.swift
Normal file
5
TelegramCore/GlobalTelegramCoreConfiguration.swift
Normal file
@@ -0,0 +1,5 @@
|
||||
import Foundation
|
||||
|
||||
public final class GlobalTelegramCoreConfiguration {
|
||||
public static var readMessages: Bool = true
|
||||
}
|
||||
50
TelegramCore/GroupFeedPeers.swift
Normal file
50
TelegramCore/GroupFeedPeers.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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> {
|
||||
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))
|
||||
|> retryRequest
|
||||
|> 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> {
|
||||
|
||||
@@ -202,7 +202,7 @@ public enum UpdatePeerAdminRightsError {
|
||||
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
|
||||
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) {
|
||||
|
||||
@@ -64,7 +64,7 @@ public enum ResolvePeerByNameOptionRemote {
|
||||
public func resolvePeerByName(account: Account, name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<PeerId?, NoError> {
|
||||
var normalizedName = name
|
||||
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
|
||||
@@ -82,7 +82,6 @@ public func resolvePeerByName(account: Account, name: String, ageLimit: Int32 =
|
||||
return account.postbox.modify { modifier -> PeerId? in
|
||||
var peerId: PeerId? = nil
|
||||
|
||||
//contacts.resolvedPeer peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;
|
||||
switch result {
|
||||
case let .resolvedPeer(apiPeer, chats, users):
|
||||
var peers: [PeerId: Peer] = [:]
|
||||
|
||||
@@ -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>) {
|
||||
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeGroupedPeers
|
||||
let peerId = PeerId(namespace: 0, id: groupId.rawValue)
|
||||
|
||||
@@ -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> {
|
||||
#if (arch(i386) || arch(x86_64)) && os(iOS)
|
||||
//return .single(readState)
|
||||
#endif
|
||||
if !GlobalTelegramCoreConfiguration.readMessages {
|
||||
return .single(readState)
|
||||
}
|
||||
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
return inputSecretChat(postbox: postbox, peerId: peerId)
|
||||
|
||||
@@ -78,6 +78,10 @@ public struct TelegramChannelGroupFlags: OptionSet {
|
||||
public struct TelegramChannelGroupInfo: Equatable {
|
||||
public let flags: TelegramChannelGroupFlags
|
||||
|
||||
public init(flags: TelegramChannelGroupFlags) {
|
||||
self.flags = flags
|
||||
}
|
||||
|
||||
public static func ==(lhs: TelegramChannelGroupInfo, rhs: TelegramChannelGroupInfo) -> Bool {
|
||||
return lhs.flags == rhs.flags
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
case gameScore(gameId: Int64, score: Int32)
|
||||
case phoneCall(callId: Int64, discardReason: PhoneCallDiscardReason?, duration: Int32?)
|
||||
case paymentSent(currency: String, totalAmount: Int64)
|
||||
case customText(text: String)
|
||||
case customText(text: String, entities: [MessageTextEntity])
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
@@ -69,7 +69,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
case 15:
|
||||
self = .paymentSent(currency: decoder.decodeStringForKey("currency", orElse: ""), totalAmount: decoder.decodeInt64ForKey("ta", orElse: 0))
|
||||
case 16:
|
||||
self = .customText(text: decoder.decodeStringForKey("text", orElse: ""))
|
||||
self = .customText(text: decoder.decodeStringForKey("text", orElse: ""), entities: decoder.decodeObjectArrayWithDecoderForKey("ent"))
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
@@ -140,9 +140,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "d")
|
||||
}
|
||||
case let .customText(text):
|
||||
case let .customText(text, entities):
|
||||
encoder.encodeInt32(16, forKey: "_rawValue")
|
||||
encoder.encodeString(text, forKey: "text")
|
||||
encoder.encodeObjectArray(entities, forKey: "ent")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,8 +263,8 @@ public func ==(lhs: TelegramMediaActionType, rhs: TelegramMediaActionType) -> Bo
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .customText(text):
|
||||
if case .customText(text) = rhs {
|
||||
case let .customText(lhsText, lhsEntities):
|
||||
if case let .customText(rhsText, rhsEntities) = rhs, lhsText == rhsText, lhsEntities == rhsEntities {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@@ -343,7 +344,7 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
||||
case .messageActionScreenshotTaken:
|
||||
return TelegramMediaAction(action: .historyScreenshot)
|
||||
case let .messageActionCustomAction(message):
|
||||
return TelegramMediaAction(action: .customText(text: message))
|
||||
return TelegramMediaAction(action: .customText(text: message, entities: []))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user