no message

This commit is contained in:
Peter Iakovlev
2018-04-20 23:33:21 +04:00
parent 66443493c0
commit 1fb868b9ff
4 changed files with 184 additions and 21 deletions

View File

@@ -366,6 +366,8 @@
D07827BB1E00451F00071108 /* SearchPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827BA1E00451F00071108 /* SearchPeers.swift */; };
D07827C91E02F59C00071108 /* InstantPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827C81E02F59C00071108 /* InstantPage.swift */; };
D07827CB1E02F5B200071108 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827CA1E02F5B200071108 /* RichText.swift */; };
D07E413F208A769D00FCA8F0 /* ProxyServersStatuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07E413E208A769D00FCA8F0 /* ProxyServersStatuses.swift */; };
D07E4140208A769D00FCA8F0 /* ProxyServersStatuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07E413E208A769D00FCA8F0 /* ProxyServersStatuses.swift */; };
D08774FC1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FB1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift */; };
D08774FE1E3E3A3500A97350 /* GlobalNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FD1E3E3A3500A97350 /* GlobalNotificationSettings.swift */; };
D08CAA7D1ED77EE90000FDA8 /* LocalizationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA7C1ED77EE90000FDA8 /* LocalizationSettings.swift */; };
@@ -895,6 +897,7 @@
D07827BA1E00451F00071108 /* SearchPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchPeers.swift; sourceTree = "<group>"; };
D07827C81E02F59C00071108 /* InstantPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPage.swift; sourceTree = "<group>"; };
D07827CA1E02F5B200071108 /* RichText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichText.swift; sourceTree = "<group>"; };
D07E413E208A769D00FCA8F0 /* ProxyServersStatuses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyServersStatuses.swift; sourceTree = "<group>"; };
D08774FB1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedGlobalNotificationSettings.swift; sourceTree = "<group>"; };
D08774FD1E3E3A3500A97350 /* GlobalNotificationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalNotificationSettings.swift; sourceTree = "<group>"; };
D08CAA7C1ED77EE90000FDA8 /* LocalizationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationSettings.swift; sourceTree = "<group>"; };
@@ -1512,6 +1515,7 @@
D0FA0ABC1E76C908005BB9B7 /* TwoStepVerification.swift */,
D0F53BE81E784A4800117362 /* ChangeAccountPhoneNumber.swift */,
9FC8ADAA206BBFF10094F7B4 /* RecentWebSessions.swift */,
D07E413E208A769D00FCA8F0 /* ProxyServersStatuses.swift */,
);
name = Settings;
sourceTree = "<group>";
@@ -2287,6 +2291,7 @@
D03B0D081D62255C00955575 /* ChannelState.swift in Sources */,
C251D7431E65E50500283EDE /* StickerSetInstallation.swift in Sources */,
D07047BA1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
D07E413F208A769D00FCA8F0 /* ProxyServersStatuses.swift in Sources */,
D0C0B58D1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -2463,6 +2468,7 @@
D0F3A8A01E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift in Sources */,
D0BE383F1E7C5995000079AF /* MediaPool.swift in Sources */,
D050F2601E4A5AD500988324 /* AutoremoveTimeoutMessageAttribute.swift in Sources */,
D07E4140208A769D00FCA8F0 /* ProxyServersStatuses.swift in Sources */,
D049EAD91E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,

View File

@@ -441,8 +441,8 @@ private final class NetworkHelper: NSObject, MTContextChangeListener {
public final class Network: NSObject, MTRequestMessageServiceDelegate {
private let queue: Queue
let datacenterId: Int
let context: MTContext
public let datacenterId: Int
public let context: MTContext
let mtProto: MTProto
let requestService: MTRequestMessageService
let basePath: String

View File

@@ -0,0 +1,141 @@
import Foundation
#if os(macOS)
import SwiftSignalKitMac
import MtProtoKitMac
#else
import SwiftSignalKit
import MtProtoKitDynamic
#endif
public enum ProxyServerStatus: Equatable {
case checking
case notAvailable
case available(Double)
}
private final class ProxyServerItemContext {
private var disposable: Disposable?
var value: ProxyServerStatus = .checking
init(queue: Queue, context: MTContext, datacenterId: Int, server: ProxyServerSettings, updated: @escaping (ProxyServerStatus) -> Void) {
self.disposable = (Signal<ProxyServerStatus, NoError> { subscriber in
let disposable = MTProxyConnectivity.pingProxy(with: context, datacenterId: datacenterId, settings: MTSocksProxySettings(ip: server.host, port: UInt16(server.port), username: server.username, password: server.password)).start(next: { next in
if let next = next as? MTProxyConnectivityStatus {
if !next.reachable {
subscriber.putNext(.notAvailable)
} else {
subscriber.putNext(.available(next.roundTripTime))
}
}
})
return ActionDisposable {
disposable?.dispose()
}
} |> runOn(queue)).start(next: { status in
updated(status)
})
}
deinit {
self.disposable?.dispose()
}
}
final class ProxyServersStatusesImpl {
private let queue: Queue
private let account: Account
private var contexts: [ProxyServerSettings: ProxyServerItemContext] = [:]
private var serversDisposable: Disposable?
private var currentValues: [ProxyServerSettings: ProxyServerStatus] = [:] {
didSet {
self.values.set(.single(self.currentValues))
}
}
let values = Promise<[ProxyServerSettings: ProxyServerStatus]>([:])
init(queue: Queue, account: Account, servers: Signal<[ProxyServerSettings], NoError>) {
self.queue = queue
self.account = account
self.serversDisposable = (servers
|> deliverOn(self.queue)).start(next: { [weak self] servers in
if let strongSelf = self {
let validKeys = Set<ProxyServerSettings>(servers)
for key in validKeys {
if strongSelf.contexts[key] == nil {
let context = ProxyServerItemContext(queue: strongSelf.queue, context: account.network.context, datacenterId: account.network.datacenterId, server: key, updated: { value in
queue.async {
if let strongSelf = self {
strongSelf.contexts[key]?.value = value
strongSelf.updateValues()
}
}
})
strongSelf.contexts[key] = context
}
}
var removeKeys: [ProxyServerSettings] = []
for (key, _) in strongSelf.contexts {
if !validKeys.contains(key) {
removeKeys.append(key)
}
}
for key in removeKeys {
let _ = strongSelf.contexts.removeValue(forKey: key)
}
if !removeKeys.isEmpty {
strongSelf.updateValues()
}
}
})
}
deinit {
self.serversDisposable?.dispose()
}
private func updateValues() {
assert(self.queue.isCurrent())
var values: [ProxyServerSettings: ProxyServerStatus] = [:]
for (key, context) in self.contexts {
values[key] = context.value
}
self.currentValues = values
}
func dispose() {
}
}
final class ProxyServersStatuses {
private let impl: QueueLocalObject<ProxyServersStatusesImpl>
init(account: Account, servers: Signal<[ProxyServerSettings], NoError>) {
let queue = Queue()
self.impl = QueueLocalObject(queue: queue, generate: {
return ProxyServersStatusesImpl(queue: queue, account: account, servers: servers)
})
}
func dispose() {
self.impl.with { impl in
impl.dispose()
}
}
func statuses() -> Signal<[ProxyServerSettings: ProxyServerStatus], NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
self.impl.with { impl in
disposable.set(impl.values.get().start(next: { value in
subscriber.putNext(value)
}))
}
return disposable
}
}
}

View File

@@ -9,7 +9,7 @@ import Foundation
import MtProtoKitDynamic
#endif
public struct ProxyServerSettings: PostboxCoding, Equatable {
public struct ProxyServerSettings: PostboxCoding, Equatable, Hashable {
public let host: String
public let port: Int32
public let username: String?
@@ -43,6 +43,18 @@ public struct ProxyServerSettings: PostboxCoding, Equatable {
encoder.encodeNil(forKey: "password")
}
}
public var hashValue: Int {
var hash = self.host.hashValue
hash = hash &* 31 &+ self.port.hashValue
if let username = self.username {
hash = hash &* 31 &+ username.hashValue
}
if let password = self.password {
hash = hash &* 31 &+ password.hashValue
}
return hash
}
}
public struct ProxySettings: PreferencesEntry, Equatable {
@@ -110,24 +122,28 @@ public struct ProxySettings: PreferencesEntry, Equatable {
public func updateProxySettingsInteractively(postbox: Postbox, network: Network, _ f: @escaping (ProxySettings) -> ProxySettings) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Void in
var updateNetwork = false
var updatedSettings: ProxySettings?
modifier.updatePreferencesEntry(key: PreferencesKeys.proxySettings, { current in
let previous = (current as? ProxySettings) ?? ProxySettings.defaultSettings
let updated = f(previous)
updatedSettings = updated
if updated.effectiveActiveServer != previous.effectiveActiveServer {
updateNetwork = true
}
return updated
})
if updateNetwork, let updatedSettings = updatedSettings {
network.context.updateApiEnvironment { current in
return current?.withUpdatedSocksProxySettings(updatedSettings.effectiveActiveServer.flatMap { activeServer -> MTSocksProxySettings? in
return MTSocksProxySettings(ip: activeServer.host, port: UInt16(activeServer.port), username: activeServer.username, password: activeServer.password)
})
}
updateProxySettingsInteractively(modifier: modifier, network: network, f)
}
}
public func updateProxySettingsInteractively(modifier: Modifier, network: Network, _ f: @escaping (ProxySettings) -> ProxySettings) {
var updateNetwork = false
var updatedSettings: ProxySettings?
modifier.updatePreferencesEntry(key: PreferencesKeys.proxySettings, { current in
let previous = (current as? ProxySettings) ?? ProxySettings.defaultSettings
let updated = f(previous)
updatedSettings = updated
if updated.effectiveActiveServer != previous.effectiveActiveServer {
updateNetwork = true
}
return updated
})
if updateNetwork, let updatedSettings = updatedSettings {
network.context.updateApiEnvironment { current in
return current?.withUpdatedSocksProxySettings(updatedSettings.effectiveActiveServer.flatMap { activeServer -> MTSocksProxySettings? in
return MTSocksProxySettings(ip: activeServer.host, port: UInt16(activeServer.port), username: activeServer.username, password: activeServer.password)
})
}
}
}