mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-20 04:24:41 +00:00
no message
This commit is contained in:
parent
760861b8d2
commit
fbe8936d6f
@ -258,6 +258,10 @@
|
|||||||
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
||||||
D0458C881E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */; };
|
D0458C881E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */; };
|
||||||
D0458C891E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */; };
|
D0458C891E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */; };
|
||||||
|
D0467D0B20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0467D0A20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift */; };
|
||||||
|
D0467D0C20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0467D0A20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift */; };
|
||||||
|
D0467D1520D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0467D1420D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift */; };
|
||||||
|
D0467D1620D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0467D1420D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift */; };
|
||||||
D048B4AC20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */; };
|
D048B4AC20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */; };
|
||||||
D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */; };
|
D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */; };
|
||||||
D049EAD51E43D98500A2CD3A /* RecentMediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */; };
|
D049EAD51E43D98500A2CD3A /* RecentMediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */; };
|
||||||
@ -875,6 +879,8 @@
|
|||||||
D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchSecretFileResource.swift; sourceTree = "<group>"; };
|
D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchSecretFileResource.swift; sourceTree = "<group>"; };
|
||||||
D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResourceApiUtils.swift; sourceTree = "<group>"; };
|
D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResourceApiUtils.swift; sourceTree = "<group>"; };
|
||||||
D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingContentInfoMessageAttribute.swift; sourceTree = "<group>"; };
|
D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingContentInfoMessageAttribute.swift; sourceTree = "<group>"; };
|
||||||
|
D0467D0A20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizeMarkAllUnseenPersonalMessagesOperation.swift; sourceTree = "<group>"; };
|
||||||
|
D0467D1420D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift; sourceTree = "<group>"; };
|
||||||
D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedProxyInfoUpdates.swift; sourceTree = "<group>"; };
|
D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedProxyInfoUpdates.swift; sourceTree = "<group>"; };
|
||||||
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentMediaItem.swift; sourceTree = "<group>"; };
|
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentMediaItem.swift; sourceTree = "<group>"; };
|
||||||
D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedRecentStickers.swift; sourceTree = "<group>"; };
|
D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedRecentStickers.swift; sourceTree = "<group>"; };
|
||||||
@ -1419,6 +1425,8 @@
|
|||||||
D0C26D7A1FE31DAC004ABF18 /* ManagedGroupFeedReadStateSyncOperations.swift */,
|
D0C26D7A1FE31DAC004ABF18 /* ManagedGroupFeedReadStateSyncOperations.swift */,
|
||||||
D0380DB9204EF306000414AB /* MessageMediaPreuploadManager.swift */,
|
D0380DB9204EF306000414AB /* MessageMediaPreuploadManager.swift */,
|
||||||
D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */,
|
D048B4AB20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift */,
|
||||||
|
D0467D0A20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift */,
|
||||||
|
D0467D1420D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift */,
|
||||||
);
|
);
|
||||||
name = State;
|
name = State;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2089,6 +2097,7 @@
|
|||||||
D03B0D5F1D631A6900955575 /* Serialization.swift in Sources */,
|
D03B0D5F1D631A6900955575 /* Serialization.swift in Sources */,
|
||||||
D093D7F920641AA500BC3599 /* SecureIdEmailValue.swift in Sources */,
|
D093D7F920641AA500BC3599 /* SecureIdEmailValue.swift in Sources */,
|
||||||
D0C44B611FC616E200227BE0 /* SearchGroupMembers.swift in Sources */,
|
D0C44B611FC616E200227BE0 /* SearchGroupMembers.swift in Sources */,
|
||||||
|
D0467D1520D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift in Sources */,
|
||||||
D03B0D441D6319F900955575 /* CloudFileMediaResource.swift in Sources */,
|
D03B0D441D6319F900955575 /* CloudFileMediaResource.swift in Sources */,
|
||||||
D018D3371E648ACF00C5E089 /* CreateChannel.swift in Sources */,
|
D018D3371E648ACF00C5E089 /* CreateChannel.swift in Sources */,
|
||||||
D01AC9211DD5E7E500E8160F /* RequestEditMessage.swift in Sources */,
|
D01AC9211DD5E7E500E8160F /* RequestEditMessage.swift in Sources */,
|
||||||
@ -2267,6 +2276,7 @@
|
|||||||
D0561DEA1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */,
|
D0561DEA1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */,
|
||||||
D099D7461EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift in Sources */,
|
D099D7461EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift in Sources */,
|
||||||
D0E412DC206A99AE00BEE4A2 /* SecureIdValueAccessContext.swift in Sources */,
|
D0E412DC206A99AE00BEE4A2 /* SecureIdValueAccessContext.swift in Sources */,
|
||||||
|
D0467D0B20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift in Sources */,
|
||||||
D0613FCA1E60440600202CDB /* InvitationLinks.swift in Sources */,
|
D0613FCA1E60440600202CDB /* InvitationLinks.swift in Sources */,
|
||||||
D03B0D721D631ABA00955575 /* SearchMessages.swift in Sources */,
|
D03B0D721D631ABA00955575 /* SearchMessages.swift in Sources */,
|
||||||
D0DC35501DE36900000195EB /* ChatContextResult.swift in Sources */,
|
D0DC35501DE36900000195EB /* ChatContextResult.swift in Sources */,
|
||||||
@ -2468,6 +2478,7 @@
|
|||||||
D03C536A1DAD5CA9004C17B3 /* TelegramUser.swift in Sources */,
|
D03C536A1DAD5CA9004C17B3 /* TelegramUser.swift in Sources */,
|
||||||
D001F3EA1E128A1C007A8C60 /* TelegramPeerNotificationSettings.swift in Sources */,
|
D001F3EA1E128A1C007A8C60 /* TelegramPeerNotificationSettings.swift in Sources */,
|
||||||
D0E412F5206B9BDC00BEE4A2 /* SecureIdVerificationDocumentReference.swift in Sources */,
|
D0E412F5206B9BDC00BEE4A2 /* SecureIdVerificationDocumentReference.swift in Sources */,
|
||||||
|
D0467D0C20D7F1E60055C28F /* SynchronizeMarkAllUnseenPersonalMessagesOperation.swift in Sources */,
|
||||||
D0FA8BA81E1FA6DF001E855B /* TelegramSecretChat.swift in Sources */,
|
D0FA8BA81E1FA6DF001E855B /* TelegramSecretChat.swift in Sources */,
|
||||||
C23BC3881E9BE3CB00D79F92 /* ImportContact.swift in Sources */,
|
C23BC3881E9BE3CB00D79F92 /* ImportContact.swift in Sources */,
|
||||||
D0B85AC61F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
|
D0B85AC61F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
|
||||||
@ -2689,6 +2700,7 @@
|
|||||||
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
||||||
D041E3F91E535A88008C24B4 /* RemovePeerMember.swift in Sources */,
|
D041E3F91E535A88008C24B4 /* RemovePeerMember.swift in Sources */,
|
||||||
D049EAF61E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
D049EAF61E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
||||||
|
D0467D1620D7F2C90055C28F /* ManagedSynchronizeMarkAllUnseenPersonalMessagesOperations.swift in Sources */,
|
||||||
D041E3F61E535464008C24B4 /* AddPeerMember.swift in Sources */,
|
D041E3F61E535464008C24B4 /* AddPeerMember.swift in Sources */,
|
||||||
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
||||||
D0E305A81E5B5CBE00D7A3A2 /* PeerAdmins.swift in Sources */,
|
D0E305A81E5B5CBE00D7A3A2 /* PeerAdmins.swift in Sources */,
|
||||||
|
@ -260,6 +260,8 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(SecureFileMediaResource.self, f: { SecureFileMediaResource(decoder: $0) })
|
declareEncodable(SecureFileMediaResource.self, f: { SecureFileMediaResource(decoder: $0) })
|
||||||
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
||||||
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
||||||
|
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
|
||||||
|
declareEncodable(CachedRecentPeers.self, f: { CachedRecentPeers(decoder: $0) })
|
||||||
|
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
@ -780,6 +782,8 @@ public class Account {
|
|||||||
self.managedOperationsDisposable.add(managedSynchronizeConsumeMessageContentOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
self.managedOperationsDisposable.add(managedSynchronizeConsumeMessageContentOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||||
self.managedOperationsDisposable.add(managedConsumePersonalMessagesActions(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
self.managedOperationsDisposable.add(managedConsumePersonalMessagesActions(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||||
|
|
||||||
|
self.managedOperationsDisposable.add(managedSynchronizeMarkAllUnseenPersonalMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||||
|
|
||||||
let importantBackgroundOperations: [Signal<AccountRunningImportantTasks, NoError>] = [
|
let importantBackgroundOperations: [Signal<AccountRunningImportantTasks, NoError>] = [
|
||||||
managedSynchronizeChatInputStateOperations(postbox: self.postbox, network: self.network) |> map { $0 ? AccountRunningImportantTasks.other : [] },
|
managedSynchronizeChatInputStateOperations(postbox: self.postbox, network: self.network) |> map { $0 ? AccountRunningImportantTasks.other : [] },
|
||||||
self.pendingMessageManager.hasPendingMessages |> map { $0 ? AccountRunningImportantTasks.pendingMessages : [] }
|
self.pendingMessageManager.hasPendingMessages |> map { $0 ? AccountRunningImportantTasks.pendingMessages : [] }
|
||||||
|
@ -749,7 +749,13 @@ private func finalStateWithUpdatesAndServerTime(account: Account, state: Account
|
|||||||
if let message = StoreMessage(apiMessage: apiMessage) {
|
if let message = StoreMessage(apiMessage: apiMessage) {
|
||||||
if let previousState = updatedState.chatStates[message.id.peerId] as? ChannelState {
|
if let previousState = updatedState.chatStates[message.id.peerId] as? ChannelState {
|
||||||
if previousState.pts >= pts {
|
if previousState.pts >= pts {
|
||||||
Logger.shared.log("State", "channel \(message.id.peerId) (\((updatedState.peers[message.id.peerId] as? TelegramChannel)?.title ?? "nil")) skip old message \(message.id) (\(message.text))")
|
let messageText: String
|
||||||
|
if Logger.shared.redactSensitiveData {
|
||||||
|
messageText = "[[redacted]]"
|
||||||
|
} else {
|
||||||
|
messageText = message.text
|
||||||
|
}
|
||||||
|
Logger.shared.log("State", "channel \(message.id.peerId) (\((updatedState.peers[message.id.peerId] as? TelegramChannel)?.title ?? "nil")) skip old message \(message.id) (\(messageText))")
|
||||||
} else if previousState.pts + ptsCount == pts {
|
} else if previousState.pts + ptsCount == pts {
|
||||||
if let preCachedResources = apiMessage.preCachedResources {
|
if let preCachedResources = apiMessage.preCachedResources {
|
||||||
for (resource, data) in preCachedResources {
|
for (resource, data) in preCachedResources {
|
||||||
|
@ -457,6 +457,26 @@ public final class AccountViewTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateMarkAllMentionsSeen(peerId: PeerId) {
|
||||||
|
self.queue.async {
|
||||||
|
guard let account = self.account else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = (account.postbox.transaction { transaction -> Set<MessageId> in
|
||||||
|
let ids = Set(transaction.getMessageIndicesWithTag(peerId: peerId, tag: .unseenPersonalMessage).map({ $0.id }))
|
||||||
|
if let summary = transaction.getMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), summary.count > 0 {
|
||||||
|
transaction.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: 0, maxId: summary.range.maxId)
|
||||||
|
addSynchronizeMarkAllUnseenPersonalMessagesOperation(transaction: transaction, peerId: peerId, maxId: summary.range.maxId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|> deliverOn(self.queue)).start(next: { [weak self] messageIds in
|
||||||
|
//self?.updateMarkMentionsSeenForMessageIds(messageIds: messageIds)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func updateMarkMentionsSeenForMessageIds(messageIds: Set<MessageId>) {
|
public func updateMarkMentionsSeenForMessageIds(messageIds: Set<MessageId>) {
|
||||||
self.queue.async {
|
self.queue.async {
|
||||||
var addedMessageIds: [MessageId] = []
|
var addedMessageIds: [MessageId] = []
|
||||||
|
@ -643,6 +643,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-74070332] = { return Api.InputPhoto.parse_inputPhoto($0) }
|
dict[-74070332] = { return Api.InputPhoto.parse_inputPhoto($0) }
|
||||||
dict[-567906571] = { return Api.contacts.TopPeers.parse_topPeersNotModified($0) }
|
dict[-567906571] = { return Api.contacts.TopPeers.parse_topPeersNotModified($0) }
|
||||||
dict[1891070632] = { return Api.contacts.TopPeers.parse_topPeers($0) }
|
dict[1891070632] = { return Api.contacts.TopPeers.parse_topPeers($0) }
|
||||||
|
dict[-1255369827] = { return Api.contacts.TopPeers.parse_topPeersDisabled($0) }
|
||||||
dict[1035688326] = { return Api.auth.SentCodeType.parse_sentCodeTypeApp($0) }
|
dict[1035688326] = { return Api.auth.SentCodeType.parse_sentCodeTypeApp($0) }
|
||||||
dict[-1073693790] = { return Api.auth.SentCodeType.parse_sentCodeTypeSms($0) }
|
dict[-1073693790] = { return Api.auth.SentCodeType.parse_sentCodeTypeSms($0) }
|
||||||
dict[1398007207] = { return Api.auth.SentCodeType.parse_sentCodeTypeCall($0) }
|
dict[1398007207] = { return Api.auth.SentCodeType.parse_sentCodeTypeCall($0) }
|
||||||
|
@ -1257,6 +1257,7 @@ struct contacts {
|
|||||||
enum TopPeers: TypeConstructorDescription {
|
enum TopPeers: TypeConstructorDescription {
|
||||||
case topPeersNotModified
|
case topPeersNotModified
|
||||||
case topPeers(categories: [Api.TopPeerCategoryPeers], chats: [Api.Chat], users: [Api.User])
|
case topPeers(categories: [Api.TopPeerCategoryPeers], chats: [Api.Chat], users: [Api.User])
|
||||||
|
case topPeersDisabled
|
||||||
|
|
||||||
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -1285,6 +1286,12 @@ struct contacts {
|
|||||||
for item in users {
|
for item in users {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
case .topPeersDisabled:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1255369827)
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1295,6 +1302,8 @@ struct contacts {
|
|||||||
return ("topPeersNotModified", [])
|
return ("topPeersNotModified", [])
|
||||||
case .topPeers(let categories, let chats, let users):
|
case .topPeers(let categories, let chats, let users):
|
||||||
return ("topPeers", [("categories", categories), ("chats", chats), ("users", users)])
|
return ("topPeers", [("categories", categories), ("chats", chats), ("users", users)])
|
||||||
|
case .topPeersDisabled:
|
||||||
|
return ("topPeersDisabled", [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1324,6 +1333,9 @@ struct contacts {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static func parse_topPeersDisabled(_ reader: BufferReader) -> TopPeers? {
|
||||||
|
return Api.contacts.TopPeers.topPeersDisabled
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3892,6 +3892,20 @@ extension Api {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func toggleTopPeers(enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-2062238246)
|
||||||
|
enabled.serialize(buffer, true)
|
||||||
|
return (FunctionDescription(name: "contacts.toggleTopPeers", parameters: [("enabled", enabled)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
struct help {
|
struct help {
|
||||||
static func getConfig() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Config>) {
|
static func getConfig() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Config>) {
|
||||||
|
@ -114,7 +114,7 @@ func applySecretOutgoingMessageReadActions(transaction: Transaction, id: Message
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func togglePeerUnreadMarkInteractively(postbox: Postbox, peerId: PeerId) -> Signal<Void, NoError> {
|
public func togglePeerUnreadMarkInteractively(postbox: Postbox, viewTracker: AccountViewTracker, peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
return postbox.transaction { transaction -> Void in
|
return postbox.transaction { transaction -> Void in
|
||||||
let namespace: MessageId.Namespace
|
let namespace: MessageId.Namespace
|
||||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
@ -129,6 +129,7 @@ public func togglePeerUnreadMarkInteractively(postbox: Postbox, peerId: PeerId)
|
|||||||
if let index = transaction.getTopPeerMessageIndex(peerId: peerId, namespace: namespace) {
|
if let index = transaction.getTopPeerMessageIndex(peerId: peerId, namespace: namespace) {
|
||||||
let _ = transaction.applyInteractiveReadMaxIndex(index)
|
let _ = transaction.applyInteractiveReadMaxIndex(index)
|
||||||
}
|
}
|
||||||
|
viewTracker.updateMarkAllMentionsSeen(peerId: peerId)
|
||||||
} else {
|
} else {
|
||||||
transaction.applyMarkUnread(peerId: peerId, namespace: namespace, value: true, interactive: true)
|
transaction.applyMarkUnread(peerId: peerId, namespace: namespace, value: true, interactive: true)
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ public final class Logger {
|
|||||||
|
|
||||||
public var logToFile: Bool = true
|
public var logToFile: Bool = true
|
||||||
public var logToConsole: Bool = true
|
public var logToConsole: Bool = true
|
||||||
|
public var redactSensitiveData: Bool = true
|
||||||
|
|
||||||
public static func setSharedLogger(_ logger: Logger) {
|
public static func setSharedLogger(_ logger: Logger) {
|
||||||
sharedLogger = logger
|
sharedLogger = logger
|
||||||
|
@ -12,42 +12,42 @@ import Foundation
|
|||||||
public final class LoggingSettings: PreferencesEntry, Equatable {
|
public final class LoggingSettings: PreferencesEntry, Equatable {
|
||||||
public let logToFile: Bool
|
public let logToFile: Bool
|
||||||
public let logToConsole: Bool
|
public let logToConsole: Bool
|
||||||
|
public let redactSensitiveData: Bool
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public static var defaultSettings = LoggingSettings(logToFile: true, logToConsole: true)
|
public static var defaultSettings = LoggingSettings(logToFile: true, logToConsole: true, redactSensitiveData: true)
|
||||||
#else
|
#else
|
||||||
public static var defaultSettings = LoggingSettings(logToFile: false, logToConsole: false)
|
public static var defaultSettings = LoggingSettings(logToFile: false, logToConsole: false, redactSensitiveData: true)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public init(logToFile: Bool, logToConsole: Bool) {
|
public init(logToFile: Bool, logToConsole: Bool, redactSensitiveData: Bool) {
|
||||||
self.logToFile = logToFile
|
self.logToFile = logToFile
|
||||||
self.logToConsole = logToConsole
|
self.logToConsole = logToConsole
|
||||||
|
self.redactSensitiveData = redactSensitiveData
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
self.logToFile = decoder.decodeInt32ForKey("logToFile", orElse: 0) != 0
|
self.logToFile = decoder.decodeInt32ForKey("logToFile", orElse: 0) != 0
|
||||||
self.logToConsole = decoder.decodeInt32ForKey("logToConsole", orElse: 0) != 0
|
self.logToConsole = decoder.decodeInt32ForKey("logToConsole", orElse: 0) != 0
|
||||||
|
self.redactSensitiveData = decoder.decodeInt32ForKey("redactSensitiveData", orElse: 1) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
encoder.encodeInt32(self.logToFile ? 1 : 0, forKey: "logToFile")
|
encoder.encodeInt32(self.logToFile ? 1 : 0, forKey: "logToFile")
|
||||||
encoder.encodeInt32(self.logToConsole ? 1 : 0, forKey: "logToConsole")
|
encoder.encodeInt32(self.logToConsole ? 1 : 0, forKey: "logToConsole")
|
||||||
|
encoder.encodeInt32(self.redactSensitiveData ? 1 : 0, forKey: "redactSensitiveData")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedLogToFile(_ logToFile: Bool) -> LoggingSettings {
|
public func withUpdatedLogToFile(_ logToFile: Bool) -> LoggingSettings {
|
||||||
return LoggingSettings(logToFile: logToFile, logToConsole: self.logToConsole)
|
return LoggingSettings(logToFile: logToFile, logToConsole: self.logToConsole, redactSensitiveData: self.redactSensitiveData)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedLogToConsole(_ logToConsole: Bool) -> LoggingSettings {
|
public func withUpdatedLogToConsole(_ logToConsole: Bool) -> LoggingSettings {
|
||||||
return LoggingSettings(logToFile: self.logToFile, logToConsole: logToConsole)
|
return LoggingSettings(logToFile: self.logToFile, logToConsole: logToConsole, redactSensitiveData: self.redactSensitiveData)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
public func withUpdatedRedactSensitiveData(_ redactSensitiveData: Bool) -> LoggingSettings {
|
||||||
guard let to = to as? LoggingSettings else {
|
return LoggingSettings(logToFile: self.logToFile, logToConsole: self.logToConsole, redactSensitiveData: redactSensitiveData)
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return self == to
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: LoggingSettings, rhs: LoggingSettings) -> Bool {
|
public static func ==(lhs: LoggingSettings, rhs: LoggingSettings) -> Bool {
|
||||||
@ -57,8 +57,19 @@ public final class LoggingSettings: PreferencesEntry, Equatable {
|
|||||||
if lhs.logToConsole != rhs.logToConsole {
|
if lhs.logToConsole != rhs.logToConsole {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.redactSensitiveData != rhs.redactSensitiveData {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||||
|
guard let to = to as? LoggingSettings else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return self == to
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateLoggingSettings(postbox: Postbox, _ f: @escaping (LoggingSettings) -> LoggingSettings) -> Signal<Void, NoError> {
|
public func updateLoggingSettings(postbox: Postbox, _ f: @escaping (LoggingSettings) -> LoggingSettings) -> Signal<Void, NoError> {
|
||||||
@ -77,6 +88,7 @@ public func updateLoggingSettings(postbox: Postbox, _ f: @escaping (LoggingSetti
|
|||||||
if let updated = updated {
|
if let updated = updated {
|
||||||
Logger.shared.logToFile = updated.logToFile
|
Logger.shared.logToFile = updated.logToFile
|
||||||
Logger.shared.logToConsole = updated.logToConsole
|
Logger.shared.logToConsole = updated.logToConsole
|
||||||
|
Logger.shared.redactSensitiveData = updated.redactSensitiveData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,186 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
import MtProtoKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
import MtProtoKitDynamic
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private final class ManagedSynchronizeMarkAllUnseenPersonalMessagesOperationsHelper {
|
||||||
|
var operationDisposables: [Int32: Disposable] = [:]
|
||||||
|
|
||||||
|
func update(_ entries: [PeerMergedOperationLogEntry]) -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) {
|
||||||
|
var disposeOperations: [Disposable] = []
|
||||||
|
var beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)] = []
|
||||||
|
|
||||||
|
var hasRunningOperationForPeerId = Set<PeerId>()
|
||||||
|
var validMergedIndices = Set<Int32>()
|
||||||
|
for entry in entries {
|
||||||
|
if !hasRunningOperationForPeerId.contains(entry.peerId) {
|
||||||
|
hasRunningOperationForPeerId.insert(entry.peerId)
|
||||||
|
validMergedIndices.insert(entry.mergedIndex)
|
||||||
|
|
||||||
|
if self.operationDisposables[entry.mergedIndex] == nil {
|
||||||
|
let disposable = MetaDisposable()
|
||||||
|
beginOperations.append((entry, disposable))
|
||||||
|
self.operationDisposables[entry.mergedIndex] = disposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeMergedIndices: [Int32] = []
|
||||||
|
for (mergedIndex, disposable) in self.operationDisposables {
|
||||||
|
if !validMergedIndices.contains(mergedIndex) {
|
||||||
|
removeMergedIndices.append(mergedIndex)
|
||||||
|
disposeOperations.append(disposable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for mergedIndex in removeMergedIndices {
|
||||||
|
self.operationDisposables.removeValue(forKey: mergedIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (disposeOperations, beginOperations)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reset() -> [Disposable] {
|
||||||
|
let disposables = Array(self.operationDisposables.values)
|
||||||
|
self.operationDisposables.removeAll()
|
||||||
|
return disposables
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func withTakenOperation(postbox: Postbox, peerId: PeerId, tag: PeerOperationLogTag, tagLocalIndex: Int32, _ f: @escaping (Transaction, PeerMergedOperationLogEntry?) -> Signal<Void, NoError>) -> Signal<Void, NoError> {
|
||||||
|
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
|
var result: PeerMergedOperationLogEntry?
|
||||||
|
transaction.operationLogUpdateEntry(peerId: peerId, tag: tag, tagLocalIndex: tagLocalIndex, { entry in
|
||||||
|
if let entry = entry, let _ = entry.mergedIndex, entry.contents is SynchronizeMarkAllUnseenPersonalMessagesOperation {
|
||||||
|
result = entry.mergedEntry!
|
||||||
|
return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none)
|
||||||
|
} else {
|
||||||
|
return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return f(transaction, result)
|
||||||
|
} |> switchToLatest
|
||||||
|
}
|
||||||
|
|
||||||
|
func managedSynchronizeMarkAllUnseenPersonalMessagesOperations(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
|
return Signal { _ in
|
||||||
|
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeMarkAllUnseenPersonalMessages
|
||||||
|
|
||||||
|
let helper = Atomic<ManagedSynchronizeMarkAllUnseenPersonalMessagesOperationsHelper>(value: ManagedSynchronizeMarkAllUnseenPersonalMessagesOperationsHelper())
|
||||||
|
|
||||||
|
let disposable = postbox.mergedOperationLogView(tag: tag, limit: 10).start(next: { view in
|
||||||
|
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) in
|
||||||
|
return helper.update(view.entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
for disposable in disposeOperations {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entry, disposable) in beginOperations {
|
||||||
|
let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in
|
||||||
|
if let entry = entry {
|
||||||
|
if let operation = entry.contents as? SynchronizeMarkAllUnseenPersonalMessagesOperation {
|
||||||
|
return synchronizeMarkAllUnseen(transaction: transaction, postbox: postbox, network: network, stateManager: stateManager, peerId: entry.peerId, operation: operation)
|
||||||
|
} else {
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .complete()
|
||||||
|
})
|
||||||
|
|> then(postbox.transaction { transaction -> Void in
|
||||||
|
let _ = transaction.operationLogRemoveEntry(peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex)
|
||||||
|
})
|
||||||
|
|
||||||
|
disposable.set(signal.start())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
let disposables = helper.with { helper -> [Disposable] in
|
||||||
|
return helper.reset()
|
||||||
|
}
|
||||||
|
for disposable in disposables {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum GetUnseenIdsError {
|
||||||
|
case done
|
||||||
|
case error(MTRpcError)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func synchronizeMarkAllUnseen(transaction: Transaction, postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, operation: SynchronizeMarkAllUnseenPersonalMessagesOperation) -> Signal<Void, NoError> {
|
||||||
|
guard let inputPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
let inputChannel = transaction.getPeer(peerId).flatMap(apiInputChannel)
|
||||||
|
let oneOperation: Signal<Bool, MTRpcError> = network.request(Api.functions.messages.getUnreadMentions(peer: inputPeer, offsetId: 0, addOffset: 0, limit: 100, maxId: 0, minId: 0))
|
||||||
|
|> mapToSignal { result -> Signal<[MessageId], MTRpcError> in
|
||||||
|
switch result {
|
||||||
|
case let .messages(messages, _, _):
|
||||||
|
return .single(messages.compactMap({ $0.id }))
|
||||||
|
case let .channelMessages(channelMessages):
|
||||||
|
return .single(channelMessages.messages.compactMap({ $0.id }))
|
||||||
|
case .messagesNotModified:
|
||||||
|
return .single([])
|
||||||
|
case let .messagesSlice(messagesSlice):
|
||||||
|
return .single(messagesSlice.messages.compactMap({ $0.id }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> mapToSignal { ids -> Signal<Bool, MTRpcError> in
|
||||||
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
guard let inputChannel = inputChannel else {
|
||||||
|
return .single(true)
|
||||||
|
}
|
||||||
|
return network.request(Api.functions.channels.readMessageContents(channel: inputChannel, id: ids.map { $0.id }))
|
||||||
|
|> mapToSignal { result -> Signal<Bool, MTRpcError> in
|
||||||
|
return .single(true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return network.request(Api.functions.messages.readMessageContents(id: ids.map { $0.id }))
|
||||||
|
|> mapToSignal { result -> Signal<Bool, MTRpcError> in
|
||||||
|
switch result {
|
||||||
|
case let .affectedMessages(pts, ptsCount):
|
||||||
|
stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||||
|
}
|
||||||
|
return .single(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let loopOperations: Signal<Void, GetUnseenIdsError> = (
|
||||||
|
(oneOperation
|
||||||
|
|> `catch` { error -> Signal<Bool, GetUnseenIdsError> in
|
||||||
|
return .fail(.error(error))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> mapToSignal { result -> Signal<Void, GetUnseenIdsError> in
|
||||||
|
if result {
|
||||||
|
return .fail(.done)
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> `catch` { error -> Signal<Void, GetUnseenIdsError> in
|
||||||
|
switch error {
|
||||||
|
case .done, .error:
|
||||||
|
return .fail(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> restart
|
||||||
|
)
|
||||||
|
return loopOperations
|
||||||
|
|> `catch` { _ -> Signal<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
@ -123,6 +123,7 @@ struct OperationLogTags {
|
|||||||
static let SynchronizeLocalizationUpdates = PeerOperationLogTag(value: 13)
|
static let SynchronizeLocalizationUpdates = PeerOperationLogTag(value: 13)
|
||||||
static let SynchronizeSavedStickers = PeerOperationLogTag(value: 14)
|
static let SynchronizeSavedStickers = PeerOperationLogTag(value: 14)
|
||||||
static let SynchronizeGroupedPeers = PeerOperationLogTag(value: 15)
|
static let SynchronizeGroupedPeers = PeerOperationLogTag(value: 15)
|
||||||
|
static let SynchronizeMarkAllUnseenPersonalMessages = PeerOperationLogTag(value: 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum PreferencesKeyValues: Int32 {
|
private enum PreferencesKeyValues: Int32 {
|
||||||
|
@ -7,13 +7,86 @@ import Foundation
|
|||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public func recentPeers(account: Account) -> Signal<[Peer], NoError> {
|
public enum RecentPeers {
|
||||||
let cachedPeers = account.postbox.recentPeers()
|
case peers([Peer])
|
||||||
|> take(1)
|
case disabled
|
||||||
|
}
|
||||||
|
|
||||||
let remotePeers = account.network.request(Api.functions.contacts.getTopPeers(flags: 1 << 0, offset: 0, limit: 16, hash: 0))
|
final class CachedRecentPeers: PostboxCoding {
|
||||||
|> retryRequest
|
let enabled: Bool
|
||||||
|> map { result -> ([Peer], [PeerId: PeerPresence])? in
|
let ids: [PeerId]
|
||||||
|
|
||||||
|
init(enabled: Bool, ids: [PeerId]) {
|
||||||
|
self.enabled = enabled
|
||||||
|
self.ids = ids
|
||||||
|
}
|
||||||
|
|
||||||
|
init(decoder: PostboxDecoder) {
|
||||||
|
self.enabled = decoder.decodeInt32ForKey("enabled", orElse: 0) != 0
|
||||||
|
self.ids = decoder.decodeInt64ArrayForKey("ids").map(PeerId.init)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeInt32(self.enabled ? 1 : 0, forKey: "enabled")
|
||||||
|
encoder.encodeInt64Array(self.ids.map({ $0.toInt64() }), forKey: "ids")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func cacheKey() -> ValueBoxKey {
|
||||||
|
let key = ValueBoxKey(length: 0)
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let collectionSpec = ItemCacheCollectionSpec(lowWaterItemCount: 1, highWaterItemCount: 1)
|
||||||
|
|
||||||
|
private func cachedRecentPeersEntryId() -> ItemCacheEntryId {
|
||||||
|
return ItemCacheEntryId(collectionId: 101, key: CachedRecentPeers.cacheKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
public func recentPeers(account: Account) -> Signal<RecentPeers, NoError> {
|
||||||
|
let key = PostboxViewKey.cachedItem(cachedRecentPeersEntryId())
|
||||||
|
return account.postbox.combinedView(keys: [key])
|
||||||
|
|> mapToSignal { views -> Signal<RecentPeers, NoError> in
|
||||||
|
if let value = (views.views[key] as? CachedItemView)?.value as? CachedRecentPeers {
|
||||||
|
if value.enabled {
|
||||||
|
return account.postbox.multiplePeersView(value.ids)
|
||||||
|
|> map { view -> RecentPeers in
|
||||||
|
var peers: [Peer] = []
|
||||||
|
for id in value.ids {
|
||||||
|
if let peer = view.peers[id], id != account.peerId {
|
||||||
|
peers.append(peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .peers(peers)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .single(.disabled)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .single(.peers([]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func managedUpdatedRecentPeers(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
let key = PostboxViewKey.cachedItem(cachedRecentPeersEntryId())
|
||||||
|
let peersEnabled = postbox.combinedView(keys: [key])
|
||||||
|
|> map { views -> Bool in
|
||||||
|
if let value = (views.views[key] as? CachedItemView)?.value as? CachedRecentPeers {
|
||||||
|
return value.enabled
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|
||||||
|
let updateOnce =
|
||||||
|
network.request(Api.functions.contacts.getTopPeers(flags: 1 << 0, offset: 0, limit: 16, hash: 0))
|
||||||
|
|> `catch` { _ -> Signal<Api.contacts.TopPeers, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
switch result {
|
switch result {
|
||||||
case let .topPeers(_, _, users):
|
case let .topPeers(_, _, users):
|
||||||
var peers: [Peer] = []
|
var peers: [Peer] = []
|
||||||
@ -25,39 +98,33 @@ public func recentPeers(account: Account) -> Signal<[Peer], NoError> {
|
|||||||
peerPresences[telegramUser.id] = presence
|
peerPresences[telegramUser.id] = presence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (peers, peerPresences)
|
|
||||||
case .topPeersNotModified:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return ([], [:])
|
|
||||||
}
|
|
||||||
|
|
||||||
let updatedRemotePeers = remotePeers
|
|
||||||
|> mapToSignal { peersAndPresences -> Signal<[Peer], NoError> in
|
|
||||||
if let (peers, peerPresences) = peersAndPresences {
|
|
||||||
return account.postbox.transaction { transaction -> [Peer] in
|
|
||||||
updatePeers(transaction: transaction, peers: peers, update: { return $1 })
|
updatePeers(transaction: transaction, peers: peers, update: { return $1 })
|
||||||
transaction.updatePeerPresences(peerPresences)
|
transaction.updatePeerPresences(peerPresences)
|
||||||
transaction.replaceRecentPeerIds(peers.map({ $0.id }))
|
|
||||||
return peers
|
transaction.putItemCacheEntry(id: cachedRecentPeersEntryId(), entry: CachedRecentPeers(enabled: true, ids: peers.map { $0.id }), collectionSpec: collectionSpec)
|
||||||
}
|
case .topPeersNotModified:
|
||||||
} else {
|
break
|
||||||
return .complete()
|
case .topPeersDisabled:
|
||||||
|
transaction.putItemCacheEntry(id: cachedRecentPeersEntryId(), entry: CachedRecentPeers(enabled: false, ids: []), collectionSpec: collectionSpec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cachedPeers
|
}
|
||||||
|> then(updatedRemotePeers |> filter({ !$0.isEmpty }))
|
|
||||||
|> map { peers -> [Peer] in
|
return peersEnabled |> mapToSignal { _ -> Signal<Void, NoError> in
|
||||||
return peers.filter { $0.id != account.peerId }
|
return updateOnce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func removeRecentPeer(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
public func removeRecentPeer(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
var peerIds = transaction.getRecentPeerIds()
|
guard let entry = transaction.retrieveItemCacheEntry(id: cachedRecentPeersEntryId()) as? CachedRecentPeers else {
|
||||||
if let index = peerIds.index(of: peerId) {
|
return .complete()
|
||||||
peerIds.remove(at: index)
|
}
|
||||||
transaction.replaceRecentPeerIds(peerIds)
|
|
||||||
|
if let index = entry.ids.index(of: peerId) {
|
||||||
|
var updatedIds = entry.ids
|
||||||
|
updatedIds.remove(at: index)
|
||||||
|
transaction.putItemCacheEntry(id: cachedRecentPeersEntryId(), entry: CachedRecentPeers(enabled: entry.enabled, ids: updatedIds), collectionSpec: collectionSpec)
|
||||||
}
|
}
|
||||||
if let peer = transaction.getPeer(peerId), let apiPeer = apiInputPeer(peer) {
|
if let peer = transaction.getPeer(peerId), let apiPeer = apiInputPeer(peer) {
|
||||||
return account.network.request(Api.functions.contacts.resetTopPeerRating(category: .topPeerCategoryCorrespondents, peer: apiPeer))
|
return account.network.request(Api.functions.contacts.resetTopPeerRating(category: .topPeerCategoryCorrespondents, peer: apiPeer))
|
||||||
@ -73,11 +140,39 @@ public func removeRecentPeer(account: Account, peerId: PeerId) -> Signal<Void, N
|
|||||||
} |> switchToLatest
|
} |> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateRecentPeersEnabled(postbox: Postbox, network: Network, enabled: Bool) -> Signal<Void, NoError> {
|
||||||
|
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
|
var currentValue = true
|
||||||
|
if let entry = transaction.retrieveItemCacheEntry(id: cachedRecentPeersEntryId()) as? CachedRecentPeers {
|
||||||
|
currentValue = entry.enabled
|
||||||
|
if !enabled {
|
||||||
|
transaction.putItemCacheEntry(id: cachedRecentPeersEntryId(), entry: CachedRecentPeers(enabled: false, ids: []), collectionSpec: collectionSpec)
|
||||||
|
} else {
|
||||||
|
transaction.putItemCacheEntry(id: cachedRecentPeersEntryId(), entry: CachedRecentPeers(enabled: true, ids: entry.ids), collectionSpec: collectionSpec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentValue == enabled {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.request(Api.functions.contacts.toggleTopPeers(enabled: currentValue ? .boolTrue : .boolFalse))
|
||||||
|
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||||
|
return .single(.boolFalse)
|
||||||
|
}
|
||||||
|
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
} |> switchToLatest
|
||||||
|
}
|
||||||
|
|
||||||
public func managedRecentlyUsedInlineBots(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
public func managedRecentlyUsedInlineBots(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
let remotePeers = network.request(Api.functions.contacts.getTopPeers(flags: 1 << 2, offset: 0, limit: 16, hash: 0))
|
let remotePeers = network.request(Api.functions.contacts.getTopPeers(flags: 1 << 2, offset: 0, limit: 16, hash: 0))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { result -> ([Peer], [PeerId: PeerPresence], [(PeerId, Double)])? in
|
|> map { result -> ([Peer], [PeerId: PeerPresence], [(PeerId, Double)])? in
|
||||||
switch result {
|
switch result {
|
||||||
|
case .topPeersDisabled:
|
||||||
|
break
|
||||||
case let .topPeers(categories, _, users):
|
case let .topPeers(categories, _, users):
|
||||||
var peers: [Peer] = []
|
var peers: [Peer] = []
|
||||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||||
|
@ -48,10 +48,10 @@ func apiFunctionDescription(of desc: FunctionDescription) -> String {
|
|||||||
redactParam = redactParams.contains(param.0)
|
redactParam = redactParams.contains(param.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if redactParam {
|
if redactParam, Logger.shared.redactSensitiveData {
|
||||||
result.append("[[redacted]]")
|
result.append("[[redacted]]")
|
||||||
} else {
|
} else {
|
||||||
result.append(recursiveDescription(redact: true, of: param.1))
|
result.append(recursiveDescription(redact: Logger.shared.redactSensitiveData, of: param.1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.append(")")
|
result.append(")")
|
||||||
@ -195,13 +195,7 @@ public class BoxedMessage: NSObject {
|
|||||||
|
|
||||||
override public var description: String {
|
override public var description: String {
|
||||||
get {
|
get {
|
||||||
let redact: Bool
|
return recursiveDescription(redact: Logger.shared.redactSensitiveData, of: self.body)
|
||||||
#if DEBUG
|
|
||||||
redact = true
|
|
||||||
#else
|
|
||||||
redact = true
|
|
||||||
#endif
|
|
||||||
return recursiveDescription(redact: redact, of: self.body)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
final class SynchronizeMarkAllUnseenPersonalMessagesOperation: PostboxCoding {
|
||||||
|
let maxId: MessageId.Id
|
||||||
|
|
||||||
|
init(maxId: MessageId.Id) {
|
||||||
|
self.maxId = maxId
|
||||||
|
}
|
||||||
|
|
||||||
|
init(decoder: PostboxDecoder) {
|
||||||
|
self.maxId = decoder.decodeInt32ForKey("maxId", orElse: Int32.min + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeInt32(self.maxId, forKey: "maxId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addSynchronizeMarkAllUnseenPersonalMessagesOperation(transaction: Transaction, peerId: PeerId, maxId: MessageId.Id) {
|
||||||
|
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeMarkAllUnseenPersonalMessages
|
||||||
|
|
||||||
|
var topLocalIndex: Int32?
|
||||||
|
var currentMaxId: MessageId.Id?
|
||||||
|
transaction.operationLogEnumerateEntries(peerId: peerId, tag: tag, { entry in
|
||||||
|
topLocalIndex = entry.tagLocalIndex
|
||||||
|
if let operation = entry.contents as? SynchronizeMarkAllUnseenPersonalMessagesOperation {
|
||||||
|
currentMaxId = operation.maxId
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if let topLocalIndex = topLocalIndex {
|
||||||
|
if let currentMaxId = currentMaxId, currentMaxId >= maxId {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = transaction.operationLogRemoveEntry(peerId: peerId, tag: tag, tagLocalIndex: topLocalIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.operationLogAddEntry(peerId: peerId, tag: tag, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: SynchronizeMarkAllUnseenPersonalMessagesOperation(maxId: maxId))
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user