Conflicts:
	TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift
This commit is contained in:
overtake 2017-03-10 21:43:46 +03:00
commit d3a0226f72
5 changed files with 201 additions and 8 deletions

View File

@ -115,6 +115,31 @@ public func enqueueMessages(account: Account, peerId: PeerId, messages: [Enqueue
} }
} }
public func resendMessages(account: Account, messageIds: [MessageId]) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Void in
var removeMessageIds: [MessageId] = []
for (peerId, ids) in messagesIdsGroupedByPeerId(messageIds) {
var messages: [EnqueueMessage] = []
for id in ids {
if let message = modifier.getMessage(id), !message.flags.contains(.Incoming) {
removeMessageIds.append(id)
var replyToMessageId: MessageId?
for attribute in message.attributes {
if let attribute = attribute as? ReplyMessageAttribute {
replyToMessageId = attribute.messageId
}
}
messages.append(.message(text: message.text, attributes: message.attributes, media: message.media.first, replyToMessageId: replyToMessageId))
}
}
let _ = enqueueMessages(modifier: modifier, account: account, peerId: peerId, messages: messages.map { (false, $0) })
}
modifier.deleteMessages(removeMessageIds)
}
}
func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messages: [(Bool, EnqueueMessage)]) -> [MessageId?] { func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messages: [(Bool, EnqueueMessage)]) -> [MessageId?] {
if let peer = modifier.getPeer(peerId) { if let peer = modifier.getPeer(peerId) {
var storeMessages: [StoreMessage] = [] var storeMessages: [StoreMessage] = []

View File

@ -57,7 +57,6 @@ public extension Message {
} }
} }
func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]] { func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]] {
var dict: [PeerId: [MessageId]] = [:] var dict: [PeerId: [MessageId]] = [:]
@ -73,6 +72,20 @@ func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]]
return dict return dict
} }
func messagesIdsGroupedByPeerId(_ ids: [MessageId]) -> [PeerId: [MessageId]] {
var dict: [PeerId: [MessageId]] = [:]
for id in ids {
let peerId = id.peerId
if dict[peerId] == nil {
dict[peerId] = [id]
} else {
dict[peerId]!.append(id)
}
}
return dict
}
func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer]) -> Message? { func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer]) -> Message? {
guard case let .Id(id) = message.id else { guard case let .Id(id) = message.id else {

View File

@ -32,6 +32,28 @@ public enum SelectivePrivacySettings: Equatable {
} }
} }
} }
func withEnabledPeerIds(_ peerIds: Set<PeerId>) -> SelectivePrivacySettings {
switch self {
case let .disableEveryone(enableFor):
return .disableEveryone(enableFor: enableFor.union(peerIds))
case let .enableContacts(enableFor, disableFor):
return .enableContacts(enableFor: enableFor.union(peerIds), disableFor: disableFor)
case .enableEveryone:
return self
}
}
func withDisabledPeerIds(_ peerIds: Set<PeerId>) -> SelectivePrivacySettings {
switch self {
case .disableEveryone:
return self
case let .enableContacts(enableFor, disableFor):
return .enableContacts(enableFor: enableFor, disableFor: disableFor.union(peerIds))
case let .enableEveryone(disableFor):
return .enableEveryone(disableFor: disableFor.union(peerIds))
}
}
} }
public struct AccountPrivacySettings: Equatable { public struct AccountPrivacySettings: Equatable {
@ -41,6 +63,13 @@ public struct AccountPrivacySettings: Equatable {
public let accountRemovalTimeout: Int32 public let accountRemovalTimeout: Int32
public init(presence: SelectivePrivacySettings, groupInvitations: SelectivePrivacySettings, voiceCalls: SelectivePrivacySettings, accountRemovalTimeout: Int32) {
self.presence = presence
self.groupInvitations = groupInvitations
self.voiceCalls = voiceCalls
self.accountRemovalTimeout = accountRemovalTimeout
}
public static func ==(lhs: AccountPrivacySettings, rhs: AccountPrivacySettings) -> Bool { public static func ==(lhs: AccountPrivacySettings, rhs: AccountPrivacySettings) -> Bool {
if lhs.presence != rhs.presence { if lhs.presence != rhs.presence {
return false return false
@ -59,3 +88,31 @@ public struct AccountPrivacySettings: Equatable {
return true return true
} }
} }
extension SelectivePrivacySettings {
init(apiRules: [Api.PrivacyRule]) {
var current: SelectivePrivacySettings = .disableEveryone(enableFor: Set())
var disableFor = Set<PeerId>()
var enableFor = Set<PeerId>()
for rule in apiRules {
switch rule {
case .privacyValueAllowAll:
current = .enableEveryone(disableFor: Set())
case .privacyValueAllowContacts:
current = .enableContacts(enableFor: Set(), disableFor: Set())
case let .privacyValueAllowUsers(users):
enableFor = Set(users.map { PeerId(namespace: Namespaces.Peer.CloudUser, id: $0) })
case .privacyValueDisallowAll:
current = .disableEveryone(enableFor: Set())
case .privacyValueDisallowContacts:
break
case let .privacyValueDisallowUsers(users):
disableFor = Set(users.map { PeerId(namespace: Namespaces.Peer.CloudUser, id: $0) })
}
}
self = current.withEnabledPeerIds(enableFor).withDisabledPeerIds(disableFor)
}
}

View File

@ -158,7 +158,6 @@ func processSecretChatIncomingDecryptedOperations(mediaBox: MediaBox, modifier:
} else { } else {
if let layer = SecretChatSequenceBasedLayer(rawValue: parsedLayer.rawValue) { if let layer = SecretChatSequenceBasedLayer(rawValue: parsedLayer.rawValue) {
let role = updatedState.role let role = updatedState.role
let fromSeqNo: Int32 = (topProcessedCanonicalIncomingOperationIndex + 1) * 2 + (role == .creator ? 1 : 1) let fromSeqNo: Int32 = (topProcessedCanonicalIncomingOperationIndex + 1) * 2 + (role == .creator ? 1 : 1)
let toSeqNo: Int32 = (canonicalIncomingIndex - 1) * 2 + (role == .creator ? 1 : 0) let toSeqNo: Int32 = (canonicalIncomingIndex - 1) * 2 + (role == .creator ? 1 : 0)
updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.resendOperations(layer: layer, actionGloballyUniqueId: arc4random64(), fromSeqNo: fromSeqNo, toSeqNo: toSeqNo), state: updatedState) updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: peerId, operation: SecretChatOutgoingOperationContents.resendOperations(layer: layer, actionGloballyUniqueId: arc4random64(), fromSeqNo: fromSeqNo, toSeqNo: toSeqNo), state: updatedState)
@ -545,11 +544,11 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
return nil return nil
case .decryptedMessageActionFlushHistory: case .decryptedMessageActionFlushHistory:
return nil return nil
case let .decryptedMessageActionNotifyLayer(layer): case .decryptedMessageActionNotifyLayer:
return nil return nil
case let .decryptedMessageActionReadMessages(randomIds): case .decryptedMessageActionReadMessages:
return nil return nil
case let .decryptedMessageActionScreenshotMessages(randomIds): case .decryptedMessageActionScreenshotMessages:
return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, timestamp: timestamp, flags: [.Incoming], tags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .historyScreenshot)]), []) return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, timestamp: timestamp, flags: [.Incoming], tags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .historyScreenshot)]), [])
case let .decryptedMessageActionSetMessageTTL(ttlSeconds): case let .decryptedMessageActionSetMessageTTL(ttlSeconds):
return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, timestamp: timestamp, flags: [.Incoming], tags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .messageAutoremoveTimeoutUpdated(ttlSeconds))]), []) return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, timestamp: timestamp, flags: [.Incoming], tags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .messageAutoremoveTimeoutUpdated(ttlSeconds))]), [])

View File

@ -7,19 +7,118 @@ import Foundation
import SwiftSignalKit import SwiftSignalKit
#endif #endif
public func updatedAccountPrivacySettings(account: Account) -> Signal<AccountPrivacySettings, NoError> { public func requestAccountPrivacySettings(account: Account) -> Signal<AccountPrivacySettings, NoError> {
let lastSeenPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyStatusTimestamp)) let lastSeenPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyStatusTimestamp))
let groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite)) let groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite))
let voiceCallPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyPhoneCall)) let voiceCallPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyPhoneCall))
let autoremoveTimeout = account.network.request(Api.functions.account.getAccountTTL()) let autoremoveTimeout = account.network.request(Api.functions.account.getAccountTTL())
return combineLatest(lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout) return combineLatest(lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout)
|> retryRequest |> retryRequest
|> map { lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout -> AccountPrivacySettings in |> mapToSignal { lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout -> Signal<AccountPrivacySettings, NoError> in
let accountTimeoutSeconds: Int32 let accountTimeoutSeconds: Int32
switch autoremoveTimeout { switch autoremoveTimeout {
case let .accountDaysTTL(days): case let .accountDaysTTL(days):
accountTimeoutSeconds = days * 24 * 60 * 60 accountTimeoutSeconds = days * 24 * 60 * 60
} }
return AccountPrivacySettings(presence: .enableEveryone(disableFor: Set()), groupInvitations: .enableEveryone(disableFor: Set()), voiceCalls: .enableEveryone(disableFor: Set()), accountRemovalTimeout: accountTimeoutSeconds)
let lastSeenRules: [Api.PrivacyRule]
let groupRules: [Api.PrivacyRule]
let voiceRules: [Api.PrivacyRule]
var apiUsers: [Api.User] = []
switch lastSeenPrivacy {
case let .privacyRules(rules, users):
apiUsers.append(contentsOf: users)
lastSeenRules = rules
}
switch groupPrivacy {
case let .privacyRules(rules, users):
apiUsers.append(contentsOf: users)
groupRules = rules
}
switch voiceCallPrivacy {
case let .privacyRules(rules, users):
apiUsers.append(contentsOf: users)
voiceRules = rules
}
let peers = apiUsers.map { TelegramUser(user: $0) }
return account.postbox.modify { modifier -> AccountPrivacySettings in
updatePeers(modifier: modifier, peers: peers, update: { _, updated in
return updated
})
return AccountPrivacySettings(presence: SelectivePrivacySettings(apiRules: lastSeenRules), groupInvitations: SelectivePrivacySettings(apiRules: groupRules), voiceCalls: SelectivePrivacySettings(apiRules: voiceRules), accountRemovalTimeout: accountTimeoutSeconds)
}
} }
} }
public func updateAccountRemovalTimeout(account: Account, timeout: Int32) -> Signal<Void, NoError> {
return account.network.request(Api.functions.account.setAccountTTL(ttl: .accountDaysTTL(days: timeout / (24 * 60 * 60))))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
}
public enum UpdateSelectiveAccountPrivacySettingsType {
case presence
case groupInvitations
case voiceCalls
var apiKey: Api.InputPrivacyKey {
switch self {
case .presence:
return .inputPrivacyKeyStatusTimestamp
case .groupInvitations:
return .inputPrivacyKeyChatInvite
case .voiceCalls:
return .inputPrivacyKeyPhoneCall
}
}
}
private func apiInputUsers(modifier: Modifier, peerIds: [PeerId]) -> [Api.InputUser] {
var result: [Api.InputUser] = []
for peerId in peerIds {
if let peer = modifier.getPeer(peerId), let inputUser = apiInputUser(peer) {
result.append(inputUser)
}
}
return result
}
public func updateSelectiveAccountPrivacySettings(account: Account, type: UpdateSelectiveAccountPrivacySettingsType, settings: SelectivePrivacySettings) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
var rules: [Api.InputPrivacyRule] = []
switch settings {
case let .disableEveryone(enableFor):
if !enableFor.isEmpty {
rules.append(Api.InputPrivacyRule.inputPrivacyValueAllowUsers(users: apiInputUsers(modifier: modifier, peerIds: Array(enableFor))))
}
rules.append(Api.InputPrivacyRule.inputPrivacyValueDisallowAll)
case let .enableContacts(enableFor, disableFor):
if !enableFor.isEmpty {
rules.append(Api.InputPrivacyRule.inputPrivacyValueAllowUsers(users: apiInputUsers(modifier: modifier, peerIds: Array(enableFor))))
}
if !disableFor.isEmpty {
rules.append(Api.InputPrivacyRule.inputPrivacyValueDisallowUsers(users: apiInputUsers(modifier: modifier, peerIds: Array(disableFor))))
}
rules.append(Api.InputPrivacyRule.inputPrivacyValueAllowContacts)
case let.enableEveryone(disableFor):
if !disableFor.isEmpty {
rules.append(Api.InputPrivacyRule.inputPrivacyValueDisallowUsers(users: apiInputUsers(modifier: modifier, peerIds: Array(disableFor))))
}
rules.append(Api.InputPrivacyRule.inputPrivacyValueAllowAll)
}
return account.network.request(Api.functions.account.setPrivacy(key: type.apiKey, rules: rules))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
} |> switchToLatest
}