mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-07 06:43:43 +00:00
Merge branch 'master' of https://github.com/peter-iakovlev/TelegramCore
Conflicts: TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift
This commit is contained in:
commit
d3a0226f72
@ -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?] {
|
||||
if let peer = modifier.getPeer(peerId) {
|
||||
var storeMessages: [StoreMessage] = []
|
||||
|
||||
@ -57,7 +57,6 @@ public extension Message {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]] {
|
||||
var dict: [PeerId: [MessageId]] = [:]
|
||||
|
||||
@ -73,6 +72,20 @@ func messagesIdsGroupedByPeerId(_ ids: Set<MessageId>) -> [PeerId: [MessageId]]
|
||||
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? {
|
||||
guard case let .Id(id) = message.id else {
|
||||
|
||||
@ -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 {
|
||||
@ -41,6 +63,13 @@ public struct AccountPrivacySettings: Equatable {
|
||||
|
||||
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 {
|
||||
if lhs.presence != rhs.presence {
|
||||
return false
|
||||
@ -59,3 +88,31 @@ public struct AccountPrivacySettings: Equatable {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +158,6 @@ func processSecretChatIncomingDecryptedOperations(mediaBox: MediaBox, modifier:
|
||||
} else {
|
||||
if let layer = SecretChatSequenceBasedLayer(rawValue: parsedLayer.rawValue) {
|
||||
let role = updatedState.role
|
||||
|
||||
let fromSeqNo: Int32 = (topProcessedCanonicalIncomingOperationIndex + 1) * 2 + (role == .creator ? 1 : 1)
|
||||
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)
|
||||
@ -545,11 +544,11 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
||||
return nil
|
||||
case .decryptedMessageActionFlushHistory:
|
||||
return nil
|
||||
case let .decryptedMessageActionNotifyLayer(layer):
|
||||
case .decryptedMessageActionNotifyLayer:
|
||||
return nil
|
||||
case let .decryptedMessageActionReadMessages(randomIds):
|
||||
case .decryptedMessageActionReadMessages:
|
||||
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)]), [])
|
||||
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))]), [])
|
||||
|
||||
@ -7,19 +7,118 @@ import Foundation
|
||||
import SwiftSignalKit
|
||||
#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 groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite))
|
||||
let voiceCallPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyPhoneCall))
|
||||
let autoremoveTimeout = account.network.request(Api.functions.account.getAccountTTL())
|
||||
return combineLatest(lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout)
|
||||
|> retryRequest
|
||||
|> map { lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout -> AccountPrivacySettings in
|
||||
|> mapToSignal { lastSeenPrivacy, groupPrivacy, voiceCallPrivacy, autoremoveTimeout -> Signal<AccountPrivacySettings, NoError> in
|
||||
let accountTimeoutSeconds: Int32
|
||||
switch autoremoveTimeout {
|
||||
case let .accountDaysTTL(days):
|
||||
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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user