no message

This commit is contained in:
Peter 2017-06-21 01:03:20 +03:00
parent 1248c2202c
commit b159e56133
8 changed files with 167 additions and 50 deletions

View File

@ -233,6 +233,7 @@ private var declaredEncodables: Void = {
declareEncodable(SuggestedLocalizationEntry.self, f: { SuggestedLocalizationEntry(decoder: $0) })
declareEncodable(SynchronizeLocalizationUpdatesOperation.self, f: { SynchronizeLocalizationUpdatesOperation(decoder: $0) })
declareEncodable(ChannelMessageStateVersionAttribute.self, f: { ChannelMessageStateVersionAttribute(decoder: $0) })
declareEncodable(CachedSecretChatData.self, f: { CachedSecretChatData(decoder: $0) })
return
}()

View File

@ -156,8 +156,8 @@ func managedSecretChatOutgoingOperations(postbox: Postbox, network: Network) ->
return sendServiceActionMessage(postbox: postbox, network: network, peerId: entry.peerId, action: .resendOperations(layer: layer, actionGloballyUniqueId: actionGloballyUniqueId, fromSeqNo: fromSeqNo, toSeqNo: toSeqNo), tagLocalIndex: entry.tagLocalIndex, wasDelivered: operation.delivered)
case let .screenshotMessages(layer, actionGloballyUniqueId, globallyUniqueIds):
return sendServiceActionMessage(postbox: postbox, network: network, peerId: entry.peerId, action: .screenshotMessages(layer: layer, actionGloballyUniqueId: actionGloballyUniqueId, globallyUniqueIds: globallyUniqueIds), tagLocalIndex: entry.tagLocalIndex, wasDelivered: operation.delivered)
case .terminate:
return requestTerminateSecretChat(postbox: postbox, network: network, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex)
case let .terminate(reportSpam):
return requestTerminateSecretChat(postbox: postbox, network: network, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex, reportSpam: reportSpam)
}
} else {
assertionFailure()
@ -831,12 +831,49 @@ private func sendBoxedDecryptedMessage(postbox: Postbox, network: Network, peer:
}
}
private func requestTerminateSecretChat(postbox: Postbox, network: Network, peerId: PeerId, tagLocalIndex: Int32) -> Signal<Void, NoError> {
private func requestTerminateSecretChat(postbox: Postbox, network: Network, peerId: PeerId, tagLocalIndex: Int32, reportSpam: Bool) -> Signal<Void, NoError> {
return network.request(Api.functions.messages.discardEncryption(chatId: peerId.id))
|> map { Optional($0) }
|> `catch` { _ in
return .single(nil)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
if reportSpam {
return postbox.modify { modifier -> TelegramSecretChat? in
if let peer = modifier.getPeer(peerId) as? TelegramSecretChat {
return peer
} else {
return nil
}
}
|> mapToSignal { peer -> Signal<Void, NoError> in
if let peer = peer {
return network.request(Api.functions.messages.reportEncryptedSpam(peer: Api.InputEncryptedChat.inputEncryptedChat(chatId: peer.id.id, accessHash: peer.accessHash)))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
if result != nil {
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedSecretChatData {
return current.withUpdatedReportStatus(.didReport)
} else {
return current
}
})
}
}
}
} else {
return .single(Void())
}
}
} else {
return .single(Void())
}
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
markOutgoingOperationAsCompleted(modifier: modifier, peerId: peerId, tagLocalIndex: tagLocalIndex, forceRemove: true)

View File

@ -12,7 +12,7 @@ public func removePeerChat(postbox: Postbox, peerId: PeerId, reportChatSpam: Boo
if peerId.namespace == Namespaces.Peer.SecretChat {
if let state = modifier.getPeerChatState(peerId) as? SecretChatState {
let updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate, state: state).withUpdatedEmbeddedState(.terminated)
let updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate(reportSpam: reportChatSpam), state: state).withUpdatedEmbeddedState(.terminated)
if updatedState != state {
modifier.setPeerChatState(peerId, state: updatedState)
if let peer = modifier.getPeer(peerId) as? TelegramSecretChat {

View File

@ -12,8 +12,29 @@ import Foundation
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()
if let peer = peer as? TelegramSecretChat {
return account.network.request(Api.functions.messages.reportEncryptedSpam(peer: Api.InputEncryptedChat.inputEncryptedChat(chatId: peer.id.id, accessHash: peer.accessHash)))
|> 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 if let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.reportSpam(peer: inputPeer))
|> map { Optional($0) }
@ -126,6 +147,8 @@ public func dismissReportPeer(account: Account, peerId: PeerId) -> Signal<Void,
return current.withUpdatedReportStatus(.none)
} else if let current = current as? CachedChannelData {
return current.withUpdatedReportStatus(.none)
} else if let current = current as? CachedSecretChatData {
return current.withUpdatedReportStatus(.none)
} else {
return current
}

View File

@ -113,7 +113,7 @@ enum SecretChatOutgoingOperationContents: Coding {
case pfsCommitKey(layer: SecretChatSequenceBasedLayer, actionGloballyUniqueId: Int64, rekeySessionId: Int64, keyFingerprint: Int64)
case noop(layer: SecretChatSequenceBasedLayer, actionGloballyUniqueId: Int64)
case setMessageAutoremoveTimeout(layer: SecretChatLayer, actionGloballyUniqueId: Int64, timeout: Int32, messageId: MessageId)
case terminate
case terminate(reportSpam: Bool)
init(decoder: Decoder) {
switch decoder.decodeInt32ForKey("r", orElse: 0) {
@ -146,7 +146,7 @@ enum SecretChatOutgoingOperationContents: Coding {
case SecretChatOutgoingOperationValue.setMessageAutoremoveTimeout.rawValue:
self = .setMessageAutoremoveTimeout(layer: SecretChatLayer(rawValue: decoder.decodeInt32ForKey("l", orElse: 0))!, actionGloballyUniqueId: decoder.decodeInt64ForKey("i", orElse: 0), timeout: decoder.decodeInt32ForKey("t", orElse: 0), messageId: MessageId(peerId: PeerId(decoder.decodeInt64ForKey("m.p", orElse: 0)), namespace: decoder.decodeInt32ForKey("m.n", orElse: 0), id: decoder.decodeInt32ForKey("m.i", orElse: 0)))
case SecretChatOutgoingOperationValue.terminate.rawValue:
self = .terminate
self = .terminate(reportSpam: decoder.decodeInt32ForKey("rs", orElse: 0) != 0)
default:
self = .noop(layer: SecretChatSequenceBasedLayer(rawValue: decoder.decodeInt32ForKey("l", orElse: 0))!, actionGloballyUniqueId: 0)
assertionFailure()
@ -237,8 +237,9 @@ enum SecretChatOutgoingOperationContents: Coding {
encoder.encodeInt64(messageId.peerId.toInt64(), forKey: "m.p")
encoder.encodeInt32(messageId.namespace, forKey: "m.n")
encoder.encodeInt32(messageId.id, forKey: "m.i")
case .terminate:
case let .terminate(reportSpam):
encoder.encodeInt32(SecretChatOutgoingOperationValue.terminate.rawValue, forKey: "r")
encoder.encodeInt32(reportSpam ? 1 : 0, forKey: "rs")
}
}
}

View File

@ -25,5 +25,5 @@ public struct SecretChatStateBridge {
public func terminateLegacySecretChat(modifier: Modifier, peerId: PeerId, state: SecretChatStateBridge) -> PeerChatState {
return addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate, state: state.state as! SecretChatState).withUpdatedEmbeddedState(.terminated)
return addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate(reportSpam: false), state: state.state as! SecretChatState).withUpdatedEmbeddedState(.terminated)
}

View File

@ -75,3 +75,33 @@ public final class TelegramSecretChat: Peer {
return TelegramSecretChat(id: self.id, creationDate: self.creationDate, regularPeerId: self.regularPeerId, accessHash: self.accessHash, role: self.role, embeddedState: self.embeddedState, messageAutoremoveTimeout: messageAutoremoveTimeout)
}
}
public final class CachedSecretChatData: CachedPeerData {
public let peerIds: Set<PeerId> = Set()
public let reportStatus: PeerReportStatus
public init(reportStatus: PeerReportStatus) {
self.reportStatus = reportStatus
}
public init(decoder: Decoder) {
self.reportStatus = PeerReportStatus(rawValue: decoder.decodeInt32ForKey("rs", orElse: 0))!
}
public func encode(_ encoder: Encoder) {
encoder.encodeInt32(self.reportStatus.rawValue, forKey: "rs")
}
public func isEqual(to: CachedPeerData) -> Bool {
if let to = to as? CachedSecretChatData {
return self.reportStatus == to.reportStatus
} else {
return false
}
}
func withUpdatedReportStatus(_ reportStatus: PeerReportStatus) -> CachedSecretChatData {
return CachedSecretChatData(reportStatus: reportStatus)
}
}

View File

@ -9,7 +9,7 @@ import Foundation
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) {
if let peer = modifier.getPeer(peerId) {
let cachedData = modifier.getPeerCachedData(peerId: peerId)
if let cachedData = cachedData as? CachedUserData {
@ -24,51 +24,76 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network,
if cachedData.reportStatus != .unknown {
return .complete()
}
} else if let cachedData = cachedData as? CachedSecretChatData {
if cachedData.reportStatus != .unknown {
return .complete()
}
}
return network.request(Api.functions.messages.getPeerSettings(peer: inputPeer))
|> retryRequest
|> mapToSignal { peerSettings -> Signal<Void, NoError> in
if peerId.namespace == Namespaces.Peer.SecretChat {
return postbox.modify { modifier -> Void in
let reportStatus: PeerReportStatus
switch peerSettings {
case let .peerSettings(flags):
reportStatus = (flags & (1 << 0) != 0) ? .canReport : .none
if let peer = modifier.getPeer(peerId), let associatedPeerId = peer.associatedPeerId, modifier.isPeerContact(peerId: associatedPeerId) {
reportStatus = .canReport
} else {
reportStatus = .canReport
}
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
})
}
modifier.updatePeerCachedData(peerIds: [peerId], update: { peerId, current in
if let current = current as? CachedSecretChatData {
return current.withUpdatedReportStatus(reportStatus)
} else {
return CachedSecretChatData(reportStatus: reportStatus)
}
})
}
} else if let inputPeer = apiInputPeer(peer) {
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()
}
} else {
return .complete()
}