diff --git a/TelegramCore/ApplyUpdateMessage.swift b/TelegramCore/ApplyUpdateMessage.swift index d86d864f51..d1a0411881 100644 --- a/TelegramCore/ApplyUpdateMessage.swift +++ b/TelegramCore/ApplyUpdateMessage.swift @@ -194,13 +194,15 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage mapping.sort { $0.1 < $1.1 } + let latestPreviousId = mapping.map({ $0.0.id }).max() + var sentStickers: [TelegramMediaFile] = [] var sentGifs: [TelegramMediaFile] = [] var updatedGroupingKey: Int64? - if let latestIndex = mapping.last?.1 { - transaction.offsetPendingMessagesTimestamps(lowerBound: latestIndex.id, excludeIds: Set(mapping.map { $0.0.id }), timestamp: latestIndex.timestamp) + if let latestPreviousId = latestPreviousId, let latestIndex = mapping.last?.1 { + transaction.offsetPendingMessagesTimestamps(lowerBound: latestPreviousId, excludeIds: Set(mapping.map { $0.0.id }), timestamp: latestIndex.timestamp) } for (message, _, updatedMessage) in mapping { diff --git a/TelegramCore/Authorization.swift b/TelegramCore/Authorization.swift index 9c29d02a7c..f7a405b508 100644 --- a/TelegramCore/Authorization.swift +++ b/TelegramCore/Authorization.swift @@ -15,60 +15,66 @@ public enum AuthorizationCodeRequestError { case generic case phoneLimitExceeded case phoneBanned + case timeout } public func sendAuthorizationCode(account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String) -> Signal { let sendCode = Api.functions.auth.sendCode(flags: 0, phoneNumber: phoneNumber, currentNumber: nil, apiId: apiId, apiHash: apiHash) let codeAndAccount = account.network.request(sendCode, automaticFloodWait: false) - |> map { result in - return (result, account) - } |> `catch` { error -> Signal<(Api.auth.SentCode, UnauthorizedAccount), MTRpcError> in - switch (error.errorDescription ?? "") { - case Regex("(PHONE_|USER_|NETWORK_)MIGRATE_(\\d+)"): - let range = error.errorDescription.range(of: "MIGRATE_")! - let updatedMasterDatacenterId = Int32(error.errorDescription[range.upperBound ..< error.errorDescription.endIndex])! - let updatedAccount = account.changedMasterDatacenterId(updatedMasterDatacenterId) - return updatedAccount - |> mapToSignalPromotingError { updatedAccount -> Signal<(Api.auth.SentCode, UnauthorizedAccount), MTRpcError> in - return updatedAccount.network.request(sendCode, automaticFloodWait: false) - |> map { sentCode in - return (sentCode, updatedAccount) - } + |> map { result in + return (result, account) + } + |> `catch` { error -> Signal<(Api.auth.SentCode, UnauthorizedAccount), MTRpcError> in + switch (error.errorDescription ?? "") { + case Regex("(PHONE_|USER_|NETWORK_)MIGRATE_(\\d+)"): + let range = error.errorDescription.range(of: "MIGRATE_")! + let updatedMasterDatacenterId = Int32(error.errorDescription[range.upperBound ..< error.errorDescription.endIndex])! + let updatedAccount = account.changedMasterDatacenterId(updatedMasterDatacenterId) + return updatedAccount + |> mapToSignalPromotingError { updatedAccount -> Signal<(Api.auth.SentCode, UnauthorizedAccount), MTRpcError> in + return updatedAccount.network.request(sendCode, automaticFloodWait: false) + |> map { sentCode in + return (sentCode, updatedAccount) } + } case _: return .fail(error) - } } - |> mapError { error -> AuthorizationCodeRequestError in - if error.errorDescription.hasPrefix("FLOOD_WAIT") { - return .limitExceeded - } else if error.errorDescription == "PHONE_NUMBER_INVALID" { - return .invalidPhoneNumber - } else if error.errorDescription == "PHONE_NUMBER_FLOOD" { - return .phoneLimitExceeded - } else if error.errorDescription == "PHONE_NUMBER_BANNED" { - return .phoneBanned - } else { - return .generic - } + } + |> mapError { error -> AuthorizationCodeRequestError in + if error.errorDescription.hasPrefix("FLOOD_WAIT") { + return .limitExceeded + } else if error.errorDescription == "PHONE_NUMBER_INVALID" { + return .invalidPhoneNumber + } else if error.errorDescription == "PHONE_NUMBER_FLOOD" { + return .phoneLimitExceeded + } else if error.errorDescription == "PHONE_NUMBER_BANNED" { + return .phoneBanned + } else { + return .generic } + } + |> timeout(20.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.timeout)) return codeAndAccount - |> mapToSignal { (sentCode, account) -> Signal in - return account.postbox.transaction { transaction -> UnauthorizedAccount in - switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, termsOfService): - var parsedNextType: AuthorizationCodeNextType? - if let nextType = nextType { - parsedNextType = AuthorizationCodeNextType(apiType: nextType) - } - - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:))))) - } - return account - } |> mapError { _ -> AuthorizationCodeRequestError in return .generic } + |> mapToSignal { (sentCode, account) -> Signal in + return account.postbox.transaction { transaction -> UnauthorizedAccount in + switch sentCode { + case let .sentCode(_, type, phoneCodeHash, nextType, timeout, termsOfService): + var parsedNextType: AuthorizationCodeNextType? + if let nextType = nextType { + parsedNextType = AuthorizationCodeNextType(apiType: nextType) + } + + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:))))) + } + return account } + |> mapError { _ -> AuthorizationCodeRequestError in + return .generic + } + } } public func resendAuthorizationCode(account: UnauthorizedAccount) -> Signal { diff --git a/TelegramCore/EnqueueMessage.swift b/TelegramCore/EnqueueMessage.swift index 1e1586f9c3..6cc02f6096 100644 --- a/TelegramCore/EnqueueMessage.swift +++ b/TelegramCore/EnqueueMessage.swift @@ -53,6 +53,16 @@ func augmentMediaWithReference(_ mediaReference: AnyMediaReference) -> Media { } } +private func convertForwardedMediaForSecretChat(_ media: Media) -> Media { + if let file = media as? TelegramMediaFile { + return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: file.partialReference, resource: file.resource, previewRepresentations: file.previewRepresentations, mimeType: file.mimeType, size: file.size, attributes: file.attributes) + } else if let image = media as? TelegramMediaImage { + return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: image.representations, reference: image.reference, partialReference: image.partialReference) + } else { + return media + } +} + private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAttribute]) -> [MessageAttribute] { return attributes.filter { attribute in switch attribute { @@ -449,10 +459,14 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, } } - let augmentedMediaList = sourceMessage.media.map { media -> Media in + var augmentedMediaList = sourceMessage.media.map { media -> Media in return augmentMediaWithReference(.message(message: MessageReference(sourceMessage), media: media)) } + if peerId.namespace == Namespaces.Peer.SecretChat { + augmentedMediaList = augmentedMediaList.map(convertForwardedMediaForSecretChat) + } + storeMessages.append(StoreMessage(peerId: peerId, namespace: Namespaces.Message.Local, globallyUniqueId: randomId, groupingKey: localGroupingKey, timestamp: timestamp, flags: flags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: forwardInfo, authorId: authorId, text: sourceMessage.text, attributes: attributes, media: augmentedMediaList)) } } diff --git a/TelegramCore/LoggingSettings.swift b/TelegramCore/LoggingSettings.swift index 32095bd886..b9d7676454 100644 --- a/TelegramCore/LoggingSettings.swift +++ b/TelegramCore/LoggingSettings.swift @@ -15,7 +15,7 @@ public final class LoggingSettings: PreferencesEntry, Equatable { public let redactSensitiveData: Bool #if DEBUG - public static var defaultSettings = LoggingSettings(logToFile: false, logToConsole: false, redactSensitiveData: true) + public static var defaultSettings = LoggingSettings(logToFile: true, logToConsole: true, redactSensitiveData: true) #else public static var defaultSettings = LoggingSettings(logToFile: false, logToConsole: false, redactSensitiveData: true) #endif diff --git a/TelegramCore/PendingMessageManager.swift b/TelegramCore/PendingMessageManager.swift index 34c2c18ade..ed4d61139f 100644 --- a/TelegramCore/PendingMessageManager.swift +++ b/TelegramCore/PendingMessageManager.swift @@ -253,7 +253,7 @@ public final class PendingMessageManager { private func beginSendingMessages(_ ids: [MessageId]) { assert(self.queue.isCurrent()) - for id in ids { + for id in ids.sorted() { let messageContext: PendingMessageContext if let current = self.messageContexts[id] { messageContext = current @@ -284,8 +284,6 @@ public final class PendingMessageManager { if let strongSelf = self { assert(strongSelf.queue.isCurrent()) - var currentGroupId: Int64? = nil - for message in messages.filter({ !$0.flags.contains(.Sending) }).sorted(by: { $0.id < $1.id }) { guard let messageContext = strongSelf.messageContexts[message.id] else { continue @@ -300,16 +298,6 @@ public final class PendingMessageManager { } else { messageContext.state = .waitingForUploadToStart(groupId: message.groupingKey, upload: contentUploadSignal) } - - if let _ = currentGroupId, message.groupingKey != currentGroupId { - currentGroupId = nil - } else { - currentGroupId = message.groupingKey - } - } - - if let currentGroupId = currentGroupId { - strongSelf.beginSendingGroupIfPossible(groupId: currentGroupId) } } })) @@ -439,8 +427,10 @@ public final class PendingMessageManager { } self.addContextActivityIfNeeded(messageContext, peerId: id.peerId) + let queue = self.queue + messageContext.uploadDisposable.set((uploadSignal - |> deliverOn(self.queue) + |> deliverOn(queue) |> `catch` { [weak self] _ -> Signal in if let strongSelf = self { let modify = strongSelf.postbox.transaction { transaction -> Void in @@ -458,6 +448,19 @@ public final class PendingMessageManager { } } return .complete() + } + |> mapToSignal { result -> Signal in + if groupId != nil, case .content = result { + return Signal { subscriber in + queue.justDispatch { + subscriber.putNext(result) + subscriber.putCompletion() + } + return EmptyDisposable + } + } else { + return .single(result) + } }).start(next: { [weak self] next in if let strongSelf = self { assert(strongSelf.queue.isCurrent()) @@ -475,9 +478,9 @@ public final class PendingMessageManager { if let current = strongSelf.messageContexts[id] { strongSelf.beginSendingMessage(messageContext: current, messageId: id, groupId: groupId, content: content) strongSelf.updateWaitingUploads(peerId: id.peerId) - //if let groupId = groupId { - // strongSelf.beginSendingGroupIfPossible(groupId: groupId) - // } + if let groupId = groupId { + strongSelf.beginSendingGroupIfPossible(groupId: groupId) + } } } } @@ -522,10 +525,10 @@ public final class PendingMessageManager { case let .content(content): if let current = strongSelf.messageContexts[contextId] { strongSelf.beginSendingMessage(messageContext: current, messageId: contextId, groupId: groupId, content: content) - strongSelf.updateWaitingUploads(peerId: peerId) if let groupId = groupId { strongSelf.beginSendingGroupIfPossible(groupId: groupId) } + strongSelf.updateWaitingUploads(peerId: peerId) } } }