no message

This commit is contained in:
Peter 2017-02-25 20:33:35 +03:00
parent 3e83bee909
commit 28dbbddea2
12 changed files with 455 additions and 171 deletions

View File

@ -66,6 +66,12 @@
D02ABC841E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02ABC831E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift */; };
D02ABC851E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02ABC831E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift */; };
D03121021DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03121011DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift */; };
D033FEB01E61EB0200644997 /* PeerReportStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEAF1E61EB0200644997 /* PeerReportStatus.swift */; };
D033FEB11E61EB0200644997 /* PeerReportStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEAF1E61EB0200644997 /* PeerReportStatus.swift */; };
D033FEB31E61F3C000644997 /* ReportPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB21E61F3C000644997 /* ReportPeer.swift */; };
D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB21E61F3C000644997 /* ReportPeer.swift */; };
D033FEB61E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
D033FEB71E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
D03B0CB91D62233400955575 /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CB81D62233400955575 /* Either.swift */; };
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBA1D62233C00955575 /* MergeLists.swift */; };
D03B0CBD1D62234300955575 /* Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBC1D62234300955575 /* Regex.swift */; };
@ -431,6 +437,9 @@
D02ABC801E310E5D00CAE539 /* ManagedCloudChatRemoveMessagesOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedCloudChatRemoveMessagesOperations.swift; sourceTree = "<group>"; };
D02ABC831E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizePinnedCloudChatsOperations.swift; sourceTree = "<group>"; };
D03121011DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramPeerNotificationSettings.swift; sourceTree = "<group>"; };
D033FEAF1E61EB0200644997 /* PeerReportStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerReportStatus.swift; sourceTree = "<group>"; };
D033FEB21E61F3C000644997 /* ReportPeer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportPeer.swift; sourceTree = "<group>"; };
D033FEB51E61F3F900644997 /* BlockedPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockedPeers.swift; sourceTree = "<group>"; };
D03B0CB81D62233400955575 /* Either.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = "<group>"; };
D03B0CBA1D62233C00955575 /* MergeLists.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MergeLists.swift; sourceTree = "<group>"; };
D03B0CBC1D62234300955575 /* Regex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Regex.swift; sourceTree = "<group>"; };
@ -778,6 +787,7 @@
D0B843841DA6EDC4005F29E1 /* CachedChannelData.swift */,
D0B844521DAC0773005F29E1 /* TelegramUserPresence.swift */,
D00D97C61E32901700E5C2B6 /* PeerInputActivity.swift */,
D033FEAF1E61EB0200644997 /* PeerReportStatus.swift */,
);
name = Peers;
sourceTree = "<group>";
@ -1069,6 +1079,8 @@
D0E305A91E5BA02D00D7A3A2 /* ChannelBlacklist.swift */,
D0E305A61E5B5CBE00D7A3A2 /* PeerAdmins.swift */,
D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */,
D033FEB21E61F3C000644997 /* ReportPeer.swift */,
D033FEB51E61F3F900644997 /* BlockedPeers.swift */,
);
name = Peers;
sourceTree = "<group>";
@ -1278,6 +1290,7 @@
D0FA8BB01E1FEC7E001E855B /* SecretChatEncryptionConfig.swift in Sources */,
D021E0DF1DB539FC00C6B04F /* StickerPack.swift in Sources */,
D03B0D091D62255C00955575 /* EnqueueMessage.swift in Sources */,
D033FEB01E61EB0200644997 /* PeerReportStatus.swift in Sources */,
D050F2511E4A59C200988324 /* JoinLink.swift in Sources */,
D07827C91E02F59C00071108 /* InstantPage.swift in Sources */,
D07827CB1E02F5B200071108 /* RichText.swift in Sources */,
@ -1375,6 +1388,7 @@
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
D0B843971DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift in Sources */,
D0448CA21E291B14005A61A7 /* FetchSecretFileResource.swift in Sources */,
D033FEB61E61F3F900644997 /* BlockedPeers.swift in Sources */,
D00C7CCC1E3620C30080C3D5 /* CachedChannelParticipants.swift in Sources */,
D09BB6B41DB02C2B00A905C0 /* PendingMessageManager.swift in Sources */,
D0BC387B1E40D2880044D6FE /* TogglePeerChatPinned.swift in Sources */,
@ -1419,6 +1433,7 @@
D02ABC841E32183300CAE539 /* ManagedSynchronizePinnedCloudChatsOperations.swift in Sources */,
D03B0CD71D62245300955575 /* TelegramGroup.swift in Sources */,
D0B8438C1DA7CF50005F29E1 /* BotInfo.swift in Sources */,
D033FEB31E61F3C000644997 /* ReportPeer.swift in Sources */,
D021E0E21DB5401A00C6B04F /* StickerManagement.swift in Sources */,
D0BC38701E40853E0044D6FE /* UpdatePeers.swift in Sources */,
D03B0CE21D62249B00955575 /* InlineBotMessageAttribute.swift in Sources */,
@ -1465,6 +1480,7 @@
C26A37EF1E5E0C41006977AC /* ChannelParticipants.swift in Sources */,
D050F26A1E4A5B6D00988324 /* ManagedGlobalNotificationSettings.swift in Sources */,
D050F26B1E4A5B6D00988324 /* ApplyMaxReadIndexInteractively.swift in Sources */,
D033FEB11E61EB0200644997 /* PeerReportStatus.swift in Sources */,
D050F26C1E4A5B6D00988324 /* UpdatePeers.swift in Sources */,
D050F26D1E4A5B6D00988324 /* CreateGroup.swift in Sources */,
D050F26E1E4A5B6D00988324 /* RemovePeerChat.swift in Sources */,
@ -1562,6 +1578,7 @@
D0DC35521DE36908000195EB /* ChatContextResult.swift in Sources */,
D0F7AB301DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
D073CE6D1DCBCF17007511FD /* InlineBotMessageAttribute.swift in Sources */,
D033FEB71E61F3F900644997 /* BlockedPeers.swift in Sources */,
D0448C9A1E268F9A005A61A7 /* SecretApiLayer46.swift in Sources */,
D050F2611E4A5AE700988324 /* PrivacySettings.swift in Sources */,
D0B8440F1DAB91CD005F29E1 /* Either.swift in Sources */,
@ -1606,6 +1623,7 @@
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,
D0FA8BBA1E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */,
D0FA8BAE1E1FD6E2001E855B /* MemoryBufferExtensions.swift in Sources */,
D0FA8BB41E201B02001E855B /* ProcessSecretChatIncomingEncryptedOperations.swift in Sources */,
D0B844101DAB91CD005F29E1 /* MergeLists.swift in Sources */,

View File

@ -231,7 +231,7 @@ public final class AccountViewTracker {
if dataUpdated {
if let account = self.account {
context.disposable.set(fetchAndUpdateCachedPeerData(peerId: peerId, network: account.network, postbox: account.postbox).start())
context.disposable.set(combineLatest(fetchAndUpdateSupplementalCachedPeerData(peerId: peerId, network: account.network, postbox: account.postbox), fetchAndUpdateCachedPeerData(peerId: peerId, network: account.network, postbox: account.postbox)).start())
}
}
}

View File

@ -38,7 +38,7 @@ public func addPeerMember(account: Account, peerId: PeerId, memberId: PeerId) ->
if !found {
updatedParticipants.append(.member(id: memberId, invitedBy: account.peerId, invitedAt: timestamp))
}
return CachedGroupData(participants: CachedGroupParticipants(participants: updatedParticipants, version: participants.version), exportedInvitation: cachedData.exportedInvitation, botInfos: cachedData.botInfos)
return cachedData.withUpdatedParticipants(CachedGroupParticipants(participants: updatedParticipants, version: participants.version))
} else {
return cachedData
}

View File

@ -0,0 +1,45 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
public func requestUpdatePeerIsBlocked(account: Account, peerId: PeerId, isBlocked: Bool) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId), let inputUser = apiInputUser(peer) {
let signal: Signal<Api.Bool, MTRpcError>
if isBlocked {
signal = account.network.request(Api.functions.contacts.block(id: inputUser))
} else {
signal = account.network.request(Api.functions.contacts.unblock(id: inputUser))
}
return signal
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
return account.postbox.modify { modifier -> Void in
if result != nil {
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
let previous: CachedUserData
if let current = current as? CachedUserData {
previous = current
} else {
previous = CachedUserData()
}
return previous.withUpdatedIsBlocked(isBlocked)
})
}
}
}
} else {
return .complete()
}
} |> switchToLatest
}

View File

@ -91,16 +91,32 @@ public final class CachedChannelData: CachedPeerData {
public let exportedInvitation: ExportedInvitation?
public let botInfos: [CachedPeerBotInfo]
public let topParticipants: CachedChannelParticipants?
public let reportStatus: PeerReportStatus
public let pinnedMessageId: MessageId?
public let peerIds: Set<PeerId>
init(flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], topParticipants: CachedChannelParticipants?) {
init() {
self.flags = []
self.about = nil
self.participantsSummary = CachedChannelParticipantsSummary(memberCount: nil, adminCount: nil, bannedCount: nil)
self.exportedInvitation = nil
self.botInfos = []
self.topParticipants = nil
self.reportStatus = .unknown
self.pinnedMessageId = nil
self.peerIds = Set()
}
init(flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], topParticipants: CachedChannelParticipants?, reportStatus: PeerReportStatus, pinnedMessageId: MessageId?) {
self.flags = flags
self.about = about
self.participantsSummary = participantsSummary
self.exportedInvitation = exportedInvitation
self.botInfos = botInfos
self.topParticipants = topParticipants
self.reportStatus = reportStatus
self.pinnedMessageId = pinnedMessageId
var peerIds = Set<PeerId>()
if let topParticipants = topParticipants {
@ -114,12 +130,36 @@ public final class CachedChannelData: CachedPeerData {
self.peerIds = peerIds
}
func withUpdatedTopParticipants(_ topParticipants: CachedChannelParticipants?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: topParticipants)
func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
return CachedChannelData(flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedAbout(_ about: String?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedTopParticipants(_ topParticipants: CachedChannelParticipants?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedReportStatus(_ reportStatus: PeerReportStatus) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: reportStatus, pinnedMessageId: self.pinnedMessageId)
}
func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: pinnedMessageId)
}
public init(decoder: Decoder) {
@ -130,6 +170,13 @@ public final class CachedChannelData: CachedPeerData {
self.botInfos = decoder.decodeObjectArrayWithDecoderForKey("b") as [CachedPeerBotInfo]
var peerIds = Set<PeerId>()
self.topParticipants = decoder.decodeObjectForKey("p", decoder: { CachedChannelParticipants(decoder: $0) }) as? CachedChannelParticipants
self.reportStatus = PeerReportStatus(rawValue: decoder.decodeInt32ForKey("r"))!
if let pinnedMessagePeerId = (decoder.decodeInt64ForKey("pm.p") as Int64?), let pinnedMessageNamespace = (decoder.decodeInt32ForKey("pm.n") as Int32?), let pinnedMessageId = (decoder.decodeInt32ForKey("pm.i") as Int32?) {
self.pinnedMessageId = MessageId(peerId: PeerId(pinnedMessagePeerId), namespace: pinnedMessageNamespace, id: pinnedMessageId)
} else {
self.pinnedMessageId = nil
}
if let topParticipants = self.topParticipants {
for participant in topParticipants.participants {
peerIds.insert(participant.peerId)
@ -161,6 +208,16 @@ public final class CachedChannelData: CachedPeerData {
} else {
encoder.encodeNil(forKey: "p")
}
encoder.encodeInt32(self.reportStatus.rawValue, forKey: "r")
if let pinnedMessageId = self.pinnedMessageId {
encoder.encodeInt64(pinnedMessageId.peerId.toInt64(), forKey: "pm.p")
encoder.encodeInt32(pinnedMessageId.namespace, forKey: "pm.n")
encoder.encodeInt32(pinnedMessageId.id, forKey: "pm.i")
} else {
encoder.encodeNil(forKey: "pm.p")
encoder.encodeNil(forKey: "pm.n")
encoder.encodeNil(forKey: "pm.i")
}
}
public func isEqual(to: CachedPeerData) -> Bool {
@ -192,41 +249,14 @@ public final class CachedChannelData: CachedPeerData {
return false
}
if other.reportStatus != self.reportStatus {
return false
}
if other.pinnedMessageId != self.pinnedMessageId {
return false
}
return true
}
func withUpdatedAbout(_ about: String?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants)
}
func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants)
}
}
extension CachedChannelData {
convenience init?(apiChatFull: Api.ChatFull) {
switch apiChatFull {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, _, pinnedMsgId):
var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants)
}
if (flags & (1 << 6)) != 0 {
channelFlags.insert(.canChangeUsername)
}
var botInfos: [CachedPeerBotInfo] = []
for botInfo in apiBotInfos {
switch botInfo {
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
}
self.init(flags: channelFlags, about: about, participantsSummary: CachedChannelParticipantsSummary(memberCount: participantsCount, adminCount: adminsCount, bannedCount: kickedCount), exportedInvitation: ExportedInvitation(apiExportedInvite: apiExportedInvite), botInfos: botInfos, topParticipants: nil)
case .chatFull:
return nil
}
}
}

View File

@ -33,13 +33,24 @@ public final class CachedGroupData: CachedPeerData {
public let participants: CachedGroupParticipants?
public let exportedInvitation: ExportedInvitation?
public let botInfos: [CachedPeerBotInfo]
public let reportStatus: PeerReportStatus
public let peerIds: Set<PeerId>
public init(participants: CachedGroupParticipants?, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo]) {
init() {
self.participants = nil
self.exportedInvitation = nil
self.botInfos = []
self.reportStatus = .unknown
self.peerIds = Set()
}
public init(participants: CachedGroupParticipants?, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], reportStatus: PeerReportStatus) {
self.participants = participants
self.exportedInvitation = exportedInvitation
self.botInfos = botInfos
self.reportStatus = reportStatus
var peerIds = Set<PeerId>()
if let participants = participants {
for participant in participants.participants {
@ -57,6 +68,8 @@ public final class CachedGroupData: CachedPeerData {
self.participants = participants
self.exportedInvitation = decoder.decodeObjectForKey("i", decoder: { ExportedInvitation(decoder: $0) }) as? ExportedInvitation
self.botInfos = decoder.decodeObjectArrayWithDecoderForKey("b") as [CachedPeerBotInfo]
self.reportStatus = PeerReportStatus(rawValue: decoder.decodeInt32ForKey("r"))!
var peerIds = Set<PeerId>()
if let participants = participants {
for participant in participants.participants {
@ -82,6 +95,7 @@ public final class CachedGroupData: CachedPeerData {
encoder.encodeNil(forKey: "i")
}
encoder.encodeObjectArray(self.botInfos, forKey: "b")
encoder.encodeInt32(self.reportStatus.rawValue, forKey: "r")
}
public func isEqual(to: CachedPeerData) -> Bool {
@ -89,31 +103,22 @@ public final class CachedGroupData: CachedPeerData {
return false
}
return self.participants == other.participants && self.exportedInvitation == other.exportedInvitation && self.botInfos == other.botInfos
return self.participants == other.participants && self.exportedInvitation == other.exportedInvitation && self.botInfos == other.botInfos && self.reportStatus == other.reportStatus
}
func withUpdatedParticipants(_ participants: CachedGroupParticipants?) -> CachedGroupData {
return CachedGroupData(participants: participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, reportStatus: self.reportStatus)
}
func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedGroupData {
return CachedGroupData(participants: self.participants, exportedInvitation: exportedInvitation, botInfos: self.botInfos)
return CachedGroupData(participants: self.participants, exportedInvitation: exportedInvitation, botInfos: self.botInfos, reportStatus: self.reportStatus)
}
}
extension CachedGroupData {
convenience init?(apiChatFull: Api.ChatFull) {
switch apiChatFull {
case let .chatFull(_, apiParticipants, _, _, apiExportedInvite, apiBotInfos):
var botInfos: [CachedPeerBotInfo] = []
for botInfo in apiBotInfos {
switch botInfo {
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
}
self.init(participants: CachedGroupParticipants(apiParticipants: apiParticipants), exportedInvitation: ExportedInvitation(apiExportedInvite: apiExportedInvite), botInfos: botInfos)
break
case .channelFull:
return nil
func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedGroupData {
return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: botInfos, reportStatus: self.reportStatus)
}
func withUpdatedReportStatus(_ reportStatus: PeerReportStatus) -> CachedGroupData {
return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, reportStatus: reportStatus)
}
}

View File

@ -8,17 +8,34 @@ import Foundation
public final class CachedUserData: CachedPeerData {
public let about: String?
public let botInfo: BotInfo?
public let reportStatus: PeerReportStatus
public let isBlocked: Bool
public let commonGroupCount: Int32
public let peerIds = Set<PeerId>()
init(about: String?, botInfo: BotInfo?) {
init() {
self.about = nil
self.botInfo = nil
self.reportStatus = .unknown
self.isBlocked = false
self.commonGroupCount = 0
}
init(about: String?, botInfo: BotInfo?, reportStatus: PeerReportStatus, isBlocked: Bool, commonGroupCount: Int32) {
self.about = about
self.botInfo = botInfo
self.reportStatus = reportStatus
self.isBlocked = isBlocked
self.commonGroupCount = commonGroupCount
}
public init(decoder: Decoder) {
self.about = decoder.decodeStringForKey("a")
self.botInfo = decoder.decodeObjectForKey("bi") as? BotInfo
self.reportStatus = PeerReportStatus(rawValue: decoder.decodeInt32ForKey("r"))!
self.isBlocked = decoder.decodeInt32ForKey("b") != 0
self.commonGroupCount = decoder.decodeInt32ForKey("cg")
}
public func encode(_ encoder: Encoder) {
@ -32,6 +49,9 @@ public final class CachedUserData: CachedPeerData {
} else {
encoder.encodeNil(forKey: "bi")
}
encoder.encodeInt32(self.reportStatus.rawValue, forKey: "r")
encoder.encodeInt32(self.isBlocked ? 1 : 0, forKey: "b")
encoder.encodeInt32(self.commonGroupCount, forKey: "cg")
}
public func isEqual(to: CachedPeerData) -> Bool {
@ -39,21 +59,26 @@ public final class CachedUserData: CachedPeerData {
return false
}
return other.about == self.about && other.botInfo == self.botInfo
return other.about == self.about && other.botInfo == self.botInfo && self.reportStatus == other.reportStatus && self.isBlocked == other.isBlocked && self.commonGroupCount == other.commonGroupCount
}
}
extension CachedUserData {
convenience init(apiUserFull: Api.UserFull) {
switch apiUserFull {
case let .userFull(_, _, about, _, _, _, apiBotInfo, commonChatsCount):
let botInfo: BotInfo?
if let apiBotInfo = apiBotInfo {
botInfo = BotInfo(apiBotInfo: apiBotInfo)
} else {
botInfo = nil
func withUpdatedAbout(_ about: String?) -> CachedUserData {
return CachedUserData(about: about, botInfo: self.botInfo, reportStatus: self.reportStatus, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount)
}
self.init(about: about, botInfo: botInfo)
func withUpdatedBotInfo(_ botInfo: BotInfo?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: botInfo, reportStatus: self.reportStatus, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount)
}
func withUpdatedReportStatus(_ reportStatus: PeerReportStatus) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, reportStatus: reportStatus, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount)
}
func withUpdatedIsBlocked(_ isBlocked: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, reportStatus: self.reportStatus, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount)
}
func withUpdatedCommonGroupCount(_ commonGroupCount: Int32) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, reportStatus: self.reportStatus, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount)
}
}

View File

@ -0,0 +1,8 @@
import Foundation
public enum PeerReportStatus: Int32 {
case unknown
case none
case canReport
case didReport
}

View File

@ -33,7 +33,8 @@ public func removePeerMember(account: Account, peerId: PeerId, memberId: PeerId)
break
}
}
return CachedGroupData(participants: CachedGroupParticipants(participants: updatedParticipants, version: participants.version), exportedInvitation: cachedData.exportedInvitation, botInfos: cachedData.botInfos)
return cachedData.withUpdatedParticipants(CachedGroupParticipants(participants: updatedParticipants, version: participants.version))
} else {
return cachedData
}

View File

@ -0,0 +1,47 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
public func reportPeer(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId) {
if let _ = peer as? TelegramSecretChat {
return .complete()
} else if let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.reportSpam(peer: inputPeer))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
return account.postbox.modify { modifier -> Void in
if result != nil {
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedUserData {
return current.withUpdatedReportStatus(.didReport)
} else if let current = current as? CachedGroupData {
return current.withUpdatedReportStatus(.didReport)
} else if let current = current as? CachedChannelData {
return current.withUpdatedReportStatus(.didReport)
} else {
return current
}
})
}
}
}
} else {
return .complete()
}
} else {
return .complete()
}
} |> switchToLatest
}

View File

@ -42,47 +42,10 @@ func fetchAndUpdateCachedParticipants(peerId: PeerId, network: Network, postbox:
}
})
}
/*switch result {
case let .chatFull(fullChat, chats, users):
switch fullChat {
case let .channelFull(_, _, _, _, _, _, readInboxMaxId, readOutboxMaxId, unreadCount, _, notifySettings, _, _, _, _, _):
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .chatFull:
break
}
if let cachedChannelData = CachedChannelData(apiChatFull: fullChat) {
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for chat in chats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers.append(groupOrChannel)
}
}
for user in users {
let telegramUser = TelegramUser(user: user)
peers.append(telegramUser)
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
}
}
updatePeers(modifier: modifier, peers: peers, update: { _, updated -> Peer in
return updated
})
modifier.updatePeerPresences(peerPresences)
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, currentData in
return cachedChannelData.withUpdatedTopParticipants((currentData as? CachedChannelData)?.topParticipants)
})
}
}*/
}
}
} else {
return .complete()
}
}
return .never()
}

View File

@ -7,6 +7,74 @@ import Foundation
import SwiftSignalKit
#endif
func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
let cachedData = modifier.getPeerCachedData(peerId: peerId)
if let cachedData = cachedData as? CachedUserData {
if cachedData.reportStatus != .unknown {
return .complete()
}
} else if let cachedData = cachedData as? CachedGroupData {
if cachedData.reportStatus != .unknown {
return .complete()
}
} else if let cachedData = cachedData as? CachedChannelData {
if cachedData.reportStatus != .unknown {
return .complete()
}
}
return network.request(Api.functions.messages.getPeerSettings(peer: inputPeer))
|> retryRequest
|> mapToSignal { peerSettings -> Signal<Void, NoError> in
let reportStatus: PeerReportStatus
switch peerSettings {
case let .peerSettings(flags):
reportStatus = (flags & (1 << 0) != 0) ? .canReport : .none
}
return postbox.modify { modifier -> Void in
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
switch peerId.namespace {
case Namespaces.Peer.CloudUser:
let previous: CachedUserData
if let current = current as? CachedUserData {
previous = current
} else {
previous = CachedUserData()
}
return previous.withUpdatedReportStatus(reportStatus)
case Namespaces.Peer.CloudGroup:
let previous: CachedGroupData
if let current = current as? CachedGroupData {
previous = current
} else {
previous = CachedGroupData()
}
return previous.withUpdatedReportStatus(reportStatus)
case Namespaces.Peer.CloudChannel:
let previous: CachedChannelData
if let current = current as? CachedChannelData {
previous = current
} else {
previous = CachedChannelData()
}
return previous.withUpdatedReportStatus(reportStatus)
default:
break
}
return current
})
}
}
} else {
return .complete()
}
} |> switchToLatest
}
func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> {
return postbox.loadedPeerWithId(peerId)
|> mapToSignal { peer -> Signal<Void, NoError> in
@ -16,16 +84,31 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
switch result {
case let .userFull(_, user, _, _, _, notifySettings, _, commonChatCount):
case let .userFull(_, user, _, _, _, notifySettings, _, _):
let telegramUser = TelegramUser(user: user)
updatePeers(modifier: modifier, peers: [telegramUser], update: { _, updated -> Peer in
return updated
})
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
}
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, _ in
return CachedUserData(apiUserFull: result)
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, current in
let previous: CachedUserData
if let current = current as? CachedUserData {
previous = current
} else {
previous = CachedUserData()
}
switch result {
case let .userFull(flags, _, about, _, _, _, apiBotInfo, commonChatsCount):
let botInfo: BotInfo?
if let apiBotInfo = apiBotInfo {
botInfo = BotInfo(apiBotInfo: apiBotInfo)
} else {
botInfo = nil
}
let isBlocked = (flags & (1 << 0)) != 0
return previous.withUpdatedAbout(about).withUpdatedBotInfo(botInfo).withUpdatedCommonGroupCount(commonChatsCount).withUpdatedIsBlocked(isBlocked)
}
})
}
}
@ -43,7 +126,20 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
break
}
if let cachedGroupData = CachedGroupData(apiChatFull: fullChat) {
switch fullChat {
case let .chatFull(_, apiParticipants, _, _, apiExportedInvite, apiBotInfos):
var botInfos: [CachedPeerBotInfo] = []
for botInfo in apiBotInfos {
switch botInfo {
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
}
let participants = CachedGroupParticipants(apiParticipants: apiParticipants)
let exportedInvitation = ExportedInvitation(apiExportedInvite: apiExportedInvite)
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for chat in chats {
@ -65,9 +161,18 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
modifier.updatePeerPresences(peerPresences)
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, _ in
return cachedGroupData
modifier.updatePeerCachedData(peerIds: [peerId], update: { _, current in
let previous: CachedGroupData
if let current = current as? CachedGroupData {
previous = current
} else {
previous = CachedGroupData()
}
return previous.withUpdatedParticipants(participants).withUpdatedExportedInvitation(exportedInvitation).withUpdatedBotInfos(botInfos)
})
case .channelFull:
break
}
}
}
@ -80,13 +185,36 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
switch result {
case let .chatFull(fullChat, chats, users):
switch fullChat {
case let .channelFull(_, _, _, _, _, _, readInboxMaxId, readOutboxMaxId, unreadCount, _, notifySettings, _, _, _, _, _):
case let .channelFull(_, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _):
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .chatFull:
break
}
if let cachedChannelData = CachedChannelData(apiChatFull: fullChat) {
switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, _, pinnedMsgId):
var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants)
}
if (flags & (1 << 6)) != 0 {
channelFlags.insert(.canChangeUsername)
}
var botInfos: [CachedPeerBotInfo] = []
for botInfo in apiBotInfos {
switch botInfo {
case let .botInfo(userId, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo))
}
}
var pinnedMessageId: MessageId?
if let pinnedMsgId = pinnedMsgId {
pinnedMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: pinnedMsgId)
}
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for chat in chats {
@ -108,9 +236,23 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
modifier.updatePeerPresences(peerPresences)
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, currentData in
return cachedChannelData.withUpdatedTopParticipants((currentData as? CachedChannelData)?.topParticipants)
modifier.updatePeerCachedData(peerIds: [peerId], update: { _, current in
let previous: CachedChannelData
if let current = current as? CachedChannelData {
previous = current
} else {
previous = CachedChannelData()
}
return previous.withUpdatedFlags(channelFlags)
.withUpdatedAbout(about)
.withUpdatedParticipantsSummary(CachedChannelParticipantsSummary(memberCount: participantsCount, adminCount: adminsCount, bannedCount: kickedCount))
.withUpdatedExportedInvitation(ExportedInvitation(apiExportedInvite: apiExportedInvite))
.withUpdatedBotInfos(botInfos)
.withUpdatedPinnedMessageId(pinnedMessageId)
})
case .chatFull:
break
}
}
}