diff --git a/TelegramCore/Account.swift b/TelegramCore/Account.swift index a8cc871ae1..4ba028da95 100644 --- a/TelegramCore/Account.swift +++ b/TelegramCore/Account.swift @@ -885,6 +885,16 @@ public class Account { public let notificationToken = Promise() public let voipToken = Promise() + + private var notificationTokensVersionValue = 0 { + didSet { + self.notificationTokensVersionPromise.set(self.notificationTokensVersionValue) + } + } + func updateNotificationTokensVersion() { + self.notificationTokensVersionValue += 1 + } + private let notificationTokensVersionPromise = ValuePromise(0) private let notificationTokenDisposable = MetaDisposable() private let voipTokenDisposable = MetaDisposable() @@ -1017,58 +1027,58 @@ public class Account { self.networkTypeValue.set(currentNetworkType()) - let appliedNotificationToken = self.notificationToken.get() - |> distinctUntilChanged - |> mapToSignal { token -> Signal in - var tokenString = "" - token.withUnsafeBytes { (bytes: UnsafePointer) -> Void in - for i in 0 ..< token.count { - let byte = bytes.advanced(by: i).pointee - tokenString = tokenString.appendingFormat("%02x", Int32(byte)) + let appliedNotificationToken = combineLatest(self.notificationToken.get(), self.notificationTokensVersionPromise.get()) + |> distinctUntilChanged(isEqual: { $0 == $1 }) + |> mapToSignal { token, _ -> Signal in + var tokenString = "" + token.withUnsafeBytes { (bytes: UnsafePointer) -> Void in + for i in 0 ..< token.count { + let byte = bytes.advanced(by: i).pointee + tokenString = tokenString.appendingFormat("%02x", Int32(byte)) + } + } + + var appSandbox: Api.Bool = .boolFalse + #if DEBUG + appSandbox = .boolTrue + #endif + + return masterNotificationsKey(account: self, ignoreDisabled: false) + |> mapToSignal { secret -> Signal in + return network.request(Api.functions.account.registerDevice(tokenType: 1, token: tokenString, appSandbox: appSandbox, secret: Buffer(data: secret.data), otherUids: [])) + |> retryRequest + |> mapToSignal { _ -> Signal in + return .complete() } - } - - var appSandbox: Api.Bool = .boolFalse - #if DEBUG - appSandbox = .boolTrue - #endif - - return masterNotificationsKey(account: self, ignoreDisabled: false) - |> mapToSignal { secret -> Signal in - return network.request(Api.functions.account.registerDevice(tokenType: 1, token: tokenString, appSandbox: appSandbox, secret: Buffer(data: secret.data), otherUids: [])) - |> retryRequest - |> mapToSignal { _ -> Signal in - return .complete() - } - } + } } self.notificationTokenDisposable.set(appliedNotificationToken.start()) - let appliedVoipToken = self.voipToken.get() - |> distinctUntilChanged - |> mapToSignal { token -> Signal in - var tokenString = "" - token.withUnsafeBytes { (bytes: UnsafePointer) -> Void in - for i in 0 ..< token.count { - let byte = bytes.advanced(by: i).pointee - tokenString = tokenString.appendingFormat("%02x", Int32(byte)) - } - } - - var appSandbox: Api.Bool = .boolFalse - #if DEBUG - appSandbox = .boolTrue - #endif - - return masterNotificationsKey(account: self, ignoreDisabled: false) - |> mapToSignal { secret -> Signal in - return network.request(Api.functions.account.registerDevice(tokenType: 9, token: tokenString, appSandbox: appSandbox, secret: Buffer(data: secret.data), otherUids: [])) - |> retryRequest - |> mapToSignal { _ -> Signal in - return .complete() - } + let appliedVoipToken = combineLatest(self.voipToken.get(), self.notificationTokensVersionPromise.get()) + |> distinctUntilChanged(isEqual: { $0 == $1 }) + |> mapToSignal { token, _ -> Signal in + var tokenString = "" + token.withUnsafeBytes { (bytes: UnsafePointer) -> Void in + for i in 0 ..< token.count { + let byte = bytes.advanced(by: i).pointee + tokenString = tokenString.appendingFormat("%02x", Int32(byte)) } } + + var appSandbox: Api.Bool = .boolFalse + #if DEBUG + appSandbox = .boolTrue + #endif + + return masterNotificationsKey(account: self, ignoreDisabled: false) + |> mapToSignal { secret -> Signal in + return network.request(Api.functions.account.registerDevice(tokenType: 9, token: tokenString, appSandbox: appSandbox, secret: Buffer(data: secret.data), otherUids: [])) + |> retryRequest + |> mapToSignal { _ -> Signal in + return .complete() + } + } + } self.voipTokenDisposable.set(appliedVoipToken.start()) let serviceTasksMasterBecomeMaster = shouldBeServiceTaskMaster.get() diff --git a/TelegramCore/MultipartUpload.swift b/TelegramCore/MultipartUpload.swift index ee0acf2ae6..5530391974 100644 --- a/TelegramCore/MultipartUpload.swift +++ b/TelegramCore/MultipartUpload.swift @@ -261,24 +261,26 @@ private final class MultipartUploadManager { case let .data(data): fileData = data } - let partData = self.state.transformHeader(data: fileData!.subdata(in: partOffset ..< (partOffset + partSize))) - var currentBigTotalParts: Int? = nil - if self.bigParts { - let totalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1) - currentBigTotalParts = totalParts - } - self.headerPartState = .uploading - let part = self.uploadPart(UploadPart(fileId: self.fileId, index: partIndex, data: partData, bigTotalParts: currentBigTotalParts, bigPart: self.bigParts)) - |> deliverOn(self.queue) - self.uploadingParts[0] = (partSize, part.start(error: { [weak self] _ in - self?.completed(nil) - }, completed: { [weak self] in - if let strongSelf = self { - let _ = strongSelf.uploadingParts.removeValue(forKey: 0) - strongSelf.headerPartState = .ready - strongSelf.checkState() + if let fileData = fileData { + let partData = self.state.transformHeader(data: fileData.subdata(in: partOffset ..< (partOffset + partSize))) + var currentBigTotalParts: Int? = nil + if self.bigParts { + let totalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1) + currentBigTotalParts = totalParts } - })) + self.headerPartState = .uploading + let part = self.uploadPart(UploadPart(fileId: self.fileId, index: partIndex, data: partData, bigTotalParts: currentBigTotalParts, bigPart: self.bigParts)) + |> deliverOn(self.queue) + self.uploadingParts[0] = (partSize, part.start(error: { [weak self] _ in + self?.completed(nil) + }, completed: { [weak self] in + if let strongSelf = self { + let _ = strongSelf.uploadingParts.removeValue(forKey: 0) + strongSelf.headerPartState = .ready + strongSelf.checkState() + } + })) + } case .uploading: break } diff --git a/TelegramCore/RecentAccountSessions.swift b/TelegramCore/RecentAccountSessions.swift index 2ee8e6b3f9..f20fc85754 100644 --- a/TelegramCore/RecentAccountSessions.swift +++ b/TelegramCore/RecentAccountSessions.swift @@ -9,17 +9,17 @@ import Foundation public func requestRecentAccountSessions(account: Account) -> Signal<[RecentAccountSession], NoError> { return account.network.request(Api.functions.account.getAuthorizations()) - |> retryRequest - |> map { result -> [RecentAccountSession] in - var sessions: [RecentAccountSession] = [] - switch result { - case let .authorizations(authorizations): - for authorization in authorizations { - sessions.append(RecentAccountSession(apiAuthorization: authorization)) - } - } - return sessions + |> retryRequest + |> map { result -> [RecentAccountSession] in + var sessions: [RecentAccountSession] = [] + switch result { + case let .authorizations(authorizations): + for authorization in authorizations { + sessions.append(RecentAccountSession(apiAuthorization: authorization)) + } } + return sessions + } } public enum TerminateSessionError { @@ -29,19 +29,23 @@ public enum TerminateSessionError { public func terminateAccountSession(account: Account, hash: Int64) -> Signal { return account.network.request(Api.functions.account.resetAuthorization(hash: hash)) - |> map {_ in} - |> mapError { error -> TerminateSessionError in - if error.errorCode == 406 { - return .freshReset - } - return .generic + |> mapError { error -> TerminateSessionError in + if error.errorCode == 406 { + return .freshReset } + return .generic + } + |> mapToSignal { _ -> Signal in + account.updateNotificationTokensVersion() + return .complete() + } } public func terminateOtherAccountSessions(account: Account) -> Signal { return account.network.request(Api.functions.auth.resetAuthorizations()) - |> retryRequest - |> mapToSignal { _ -> Signal in - return .complete() - } + |> retryRequest + |> mapToSignal { _ -> Signal in + account.updateNotificationTokensVersion() + return .complete() + } }