mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-25 20:50:47 +00:00
Merge commit '42673dc7f0ba37737573aa5ad95df3d916a57ceb'
This commit is contained in:
commit
74943cd1b4
@ -12,13 +12,17 @@ struct MatchingDeviceContact {
|
|||||||
let phoneNumbers: [String]
|
let phoneNumbers: [String]
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContact], NoError> {
|
enum IntentContactsError {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
|
func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContact], IntentContactsError> {
|
||||||
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
|
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
|
||||||
return .single([])
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
let store = CNContactStore()
|
let store = CNContactStore()
|
||||||
guard let contacts = try? store.unifiedContacts(matching: CNContact.predicateForContacts(withIdentifiers: stableIds), keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey as CNKeyDescriptor]) else {
|
guard let contacts = try? store.unifiedContacts(matching: CNContact.predicateForContacts(withIdentifiers: stableIds), keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey as CNKeyDescriptor]) else {
|
||||||
return .single([])
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .single(contacts.map({ contact in
|
return .single(contacts.map({ contact in
|
||||||
@ -34,19 +38,58 @@ func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContac
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func matchPhoneNumbers(_ lhs: String, _ rhs: String) -> Bool {
|
||||||
|
if lhs.count < 10 && lhs.count == rhs.count {
|
||||||
|
return lhs == rhs
|
||||||
|
} else if lhs.count >= 10 && rhs.count >= 10 && lhs.suffix(10) == rhs.suffix(10) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> {
|
func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> {
|
||||||
return postbox.transaction { transaction -> [(String, TelegramUser)] in
|
return postbox.transaction { transaction -> [(String, TelegramUser)] in
|
||||||
var result: [(String, TelegramUser)] = []
|
var result: [(String, TelegramUser)] = []
|
||||||
outer: for peerId in transaction.getContactPeerIds() {
|
outer: for peerId in transaction.getContactPeerIds() {
|
||||||
if let peer = transaction.getPeer(peerId) as? TelegramUser, let phone = peer.phone {
|
if let peer = transaction.getPeer(peerId) as? TelegramUser, let peerPhoneNumber = peer.phone {
|
||||||
for contact in contacts {
|
for contact in contacts {
|
||||||
for phoneNumber in contact.phoneNumbers {
|
for phoneNumber in contact.phoneNumbers {
|
||||||
if arePhoneNumbersEqual(phoneNumber, phone) {
|
if matchPhoneNumbers(phoneNumber, peerPhoneNumber) {
|
||||||
result.append((contact.stableId, peer))
|
result.append((contact.stableId, peer))
|
||||||
continue outer
|
continue outer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// var parsedPhoneNumbers: [String: ParsedPhoneNumber] = [:]
|
||||||
|
// let parsedPeerPhoneNumber: ParsedPhoneNumber?
|
||||||
|
// if let number = parsedPhoneNumbers[peerPhoneNumber] {
|
||||||
|
// parsedPeerPhoneNumber = number
|
||||||
|
// } else if let number = ParsedPhoneNumber(string: peerPhoneNumber) {
|
||||||
|
// parsedPeerPhoneNumber = number
|
||||||
|
// parsedPhoneNumbers[peerPhoneNumber] = number
|
||||||
|
// } else {
|
||||||
|
// parsedPeerPhoneNumber = nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for contact in contacts {
|
||||||
|
// for phoneNumber in contact.phoneNumbers {
|
||||||
|
// let parsedPhoneNumber: ParsedPhoneNumber?
|
||||||
|
// if let number = parsedPhoneNumbers[phoneNumber] {
|
||||||
|
// parsedPhoneNumber = number
|
||||||
|
// } else if let number = ParsedPhoneNumber(string: phoneNumber) {
|
||||||
|
// parsedPhoneNumber = number
|
||||||
|
// parsedPhoneNumbers[phoneNumber] = number
|
||||||
|
// } else {
|
||||||
|
// parsedPhoneNumber = nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if parsedPeerPhoneNumber == parsedPhoneNumber {
|
||||||
|
// result.append((contact.stableId, peer))
|
||||||
|
// continue outer
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -4,6 +4,7 @@ import TelegramCore
|
|||||||
import Postbox
|
import Postbox
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import BuildConfig
|
import BuildConfig
|
||||||
|
import Contacts
|
||||||
|
|
||||||
private var accountCache: Account?
|
private var accountCache: Account?
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ enum IntentHandlingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling {
|
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling {
|
||||||
private let accountPromise = Promise<Account>()
|
private let accountPromise = Promise<Account?>()
|
||||||
|
|
||||||
private let resolvePersonsDisposable = MetaDisposable()
|
private let resolvePersonsDisposable = MetaDisposable()
|
||||||
private let actionDisposable = MetaDisposable()
|
private let actionDisposable = MetaDisposable()
|
||||||
@ -86,7 +87,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|
|
||||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
||||||
|
|
||||||
let account: Signal<Account, NoError>
|
let account: Signal<Account?, NoError>
|
||||||
if let accountCache = accountCache {
|
if let accountCache = accountCache {
|
||||||
account = .single(accountCache)
|
account = .single(accountCache)
|
||||||
} else {
|
} else {
|
||||||
@ -97,7 +98,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
||||||
|
|
||||||
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: .single(buildConfig.bundleData(withAppToken: nil))), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: .single(buildConfig.bundleData(withAppToken: nil))), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|
||||||
|> mapToSignal { account -> Signal<Account, NoError> in
|
|> mapToSignal { account -> Signal<Account?, NoError> in
|
||||||
if let account = account {
|
if let account = account {
|
||||||
switch account {
|
switch account {
|
||||||
case .upgrading:
|
case .upgrading:
|
||||||
@ -117,12 +118,9 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return .complete()
|
return .single(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> afterNext { account in
|
|
||||||
account.resetStateManagement()
|
|
||||||
}
|
|
||||||
|> take(1)
|
|> take(1)
|
||||||
}
|
}
|
||||||
self.accountPromise.set(account)
|
self.accountPromise.set(account)
|
||||||
@ -138,6 +136,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func resolve(persons: [INPerson]?, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
|
private func resolve(persons: [INPerson]?, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
|
||||||
|
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
|
||||||
|
completion([INPersonResolutionResult.notRequired()])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard let initialPersons = persons, !initialPersons.isEmpty else {
|
guard let initialPersons = persons, !initialPersons.isEmpty else {
|
||||||
completion([INPersonResolutionResult.needsValue()])
|
completion([INPersonResolutionResult.needsValue()])
|
||||||
return
|
return
|
||||||
@ -205,8 +208,14 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { matchedContacts in
|
|> mapToSignal { matchedContacts in
|
||||||
return account
|
return account
|
||||||
|> mapToSignal { account in
|
|> introduceError(IntentContactsError.self)
|
||||||
return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts)
|
|> mapToSignal { account -> Signal<[(String, TelegramUser)], IntentContactsError> in
|
||||||
|
if let account = account {
|
||||||
|
return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts)
|
||||||
|
|> introduceError(IntentContactsError.self)
|
||||||
|
} else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.resolvePersonsDisposable.set((signal
|
self.resolvePersonsDisposable.set((signal
|
||||||
@ -219,6 +228,8 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
return INPersonResolutionResult.success(with: person)
|
return INPersonResolutionResult.success(with: person)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}, error: { error in
|
||||||
|
completion([INPersonResolutionResult.unsupported()])
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,14 +241,20 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
let account = self.accountPromise.get()
|
let account = self.accountPromise.get()
|
||||||
|
|
||||||
let signal = account
|
let signal = account
|
||||||
|> mapToSignal { account -> Signal<INPerson?, NoError> in
|
|> introduceError(IntentHandlingError.self)
|
||||||
return matchingCloudContact(postbox: account.postbox, peerId: PeerId(peerId))
|
|> mapToSignal { account -> Signal<INPerson?, IntentHandlingError> in
|
||||||
|> map { user -> INPerson? in
|
if let account = account {
|
||||||
if let user = user {
|
return matchingCloudContact(postbox: account.postbox, peerId: PeerId(peerId))
|
||||||
return personWithUser(stableId: "tg\(peerId)", user: user)
|
|> introduceError(IntentHandlingError.self)
|
||||||
} else {
|
|> map { user -> INPerson? in
|
||||||
return nil
|
if let user = user {
|
||||||
|
return personWithUser(stableId: "tg\(peerId)", user: user)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,6 +265,8 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
} else {
|
} else {
|
||||||
completion([INPersonResolutionResult.needsValue()])
|
completion([INPersonResolutionResult.needsValue()])
|
||||||
}
|
}
|
||||||
|
}, error: { error in
|
||||||
|
completion([INPersonResolutionResult.notRequired()])
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
self.resolve(persons: intent.recipients, with: completion)
|
self.resolve(persons: intent.recipients, with: completion)
|
||||||
@ -258,6 +277,10 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
|
func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
|
||||||
|
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
|
||||||
|
completion(INStringResolutionResult.notRequired())
|
||||||
|
return
|
||||||
|
}
|
||||||
if let text = intent.content, !text.isEmpty {
|
if let text = intent.content, !text.isEmpty {
|
||||||
completion(INStringResolutionResult.success(with: text))
|
completion(INStringResolutionResult.success(with: text))
|
||||||
} else {
|
} else {
|
||||||
@ -267,6 +290,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|
|
||||||
func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
|
func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
|
||||||
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
||||||
|
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
|
||||||
|
let response = INSendMessageIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
|
||||||
|
completion(response)
|
||||||
|
return
|
||||||
|
}
|
||||||
let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity)
|
let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity)
|
||||||
completion(response)
|
completion(response)
|
||||||
}
|
}
|
||||||
@ -278,6 +306,9 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { account -> Signal<Void, IntentHandlingError> in
|
|> mapToSignal { account -> Signal<Void, IntentHandlingError> in
|
||||||
|
guard let account = account else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
guard let recipient = intent.recipients?.first, let customIdentifier = recipient.customIdentifier, customIdentifier.hasPrefix("tg") else {
|
guard let recipient = intent.recipients?.first, let customIdentifier = recipient.customIdentifier, customIdentifier.hasPrefix("tg") else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -305,7 +336,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
||||||
let response = INSendMessageIntentResponse(code: .failure, userActivity: userActivity)
|
let response = INSendMessageIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
|
||||||
completion(response)
|
completion(response)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
|
||||||
@ -325,18 +356,27 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
|> mapToSignal { account -> Signal<[INMessage], IntentHandlingError> in
|
|> mapToSignal { account -> Signal<[INMessage], IntentHandlingError> in
|
||||||
|
guard let account = account else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.now))
|
account.shouldBeServiceTaskMaster.set(.single(.now))
|
||||||
account.resetStateManagement()
|
account.resetStateManagement()
|
||||||
|
|
||||||
return account.stateManager.pollStateUpdateCompletion()
|
let completion: Signal<Void, NoError> = account.stateManager.pollStateUpdateCompletion()
|
||||||
|
|> map { _ in
|
||||||
|
return Void()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (completion |> timeout(4.0, queue: Queue.mainQueue(), alternate: .single(Void())))
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { _ -> Signal<[INMessage], IntentHandlingError> in
|
|> mapToSignal { _ -> Signal<[INMessage], IntentHandlingError> in
|
||||||
return unreadMessages(account: account)
|
return unreadMessages(account: account)
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
}
|
|> afterDisposed {
|
||||||
|> afterDisposed {
|
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { messages in
|
|> deliverOnMainQueue).start(next: { messages in
|
||||||
@ -346,7 +386,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
completion(response)
|
completion(response)
|
||||||
}, error: { _ in
|
}, error: { _ in
|
||||||
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self))
|
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self))
|
||||||
let response = INSearchForMessagesIntentResponse(code: .failure, userActivity: userActivity)
|
let response = INSearchForMessagesIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
|
||||||
completion(response)
|
completion(response)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -373,8 +413,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { account -> Signal<Void, IntentHandlingError> in
|
|> mapToSignal { account -> Signal<Void, IntentHandlingError> in
|
||||||
var signals: [Signal<Void, IntentHandlingError>] = []
|
guard let account = account else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
|
||||||
|
var signals: [Signal<Void, IntentHandlingError>] = []
|
||||||
var maxMessageIdsToApply: [PeerId: MessageId] = [:]
|
var maxMessageIdsToApply: [PeerId: MessageId] = [:]
|
||||||
if let identifiers = intent.identifiers {
|
if let identifiers = intent.identifiers {
|
||||||
for identifier in identifiers {
|
for identifier in identifiers {
|
||||||
@ -478,6 +521,10 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
|> mapToSignal { account -> Signal<[CallRecord], IntentHandlingError> in
|
|> mapToSignal { account -> Signal<[CallRecord], IntentHandlingError> in
|
||||||
|
guard let account = account else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.now))
|
account.shouldBeServiceTaskMaster.set(.single(.now))
|
||||||
return missedCalls(account: account)
|
return missedCalls(account: account)
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
@ -497,7 +544,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
completion(response)
|
completion(response)
|
||||||
}, error: { _ in
|
}, error: { _ in
|
||||||
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchCallHistoryIntent.self))
|
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchCallHistoryIntent.self))
|
||||||
let response = INSearchCallHistoryIntentResponse(code: .failure, userActivity: userActivity)
|
let response = INSearchCallHistoryIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
|
||||||
completion(response)
|
completion(response)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,10 @@ func unreadMessages(account: Account) -> Signal<[INMessage], NoError> {
|
|||||||
var signals: [Signal<[INMessage], NoError>] = []
|
var signals: [Signal<[INMessage], NoError>] = []
|
||||||
for entry in view.0.entries {
|
for entry in view.0.entries {
|
||||||
if case let .MessageEntry(index, _, readState, notificationSettings, _, _, _, _) = entry {
|
if case let .MessageEntry(index, _, readState, notificationSettings, _, _, _, _) = entry {
|
||||||
|
if index.messageIndex.id.peerId.namespace != Namespaces.Peer.CloudUser {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var hasUnread = false
|
var hasUnread = false
|
||||||
var fixedCombinedReadStates: MessageHistoryViewReadState?
|
var fixedCombinedReadStates: MessageHistoryViewReadState?
|
||||||
if let readState = readState {
|
if let readState = readState {
|
||||||
@ -133,7 +137,7 @@ private func callWithTelegramMessage(_ telegramMessage: Message, account: Accoun
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func messageWithTelegramMessage(_ telegramMessage: Message, account: Account) -> INMessage? {
|
private func messageWithTelegramMessage(_ telegramMessage: Message, account: Account) -> INMessage? {
|
||||||
guard let author = telegramMessage.author, let user = telegramMessage.peers[author.id] as? TelegramUser else {
|
guard let author = telegramMessage.author, let user = telegramMessage.peers[author.id] as? TelegramUser, user.id.id != 777000 else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,9 +198,16 @@ private func messageWithTelegramMessage(_ telegramMessage: Message, account: Acc
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if telegramMessage.text.isEmpty && messageType == .text {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
message = INMessage(identifier: identifier, conversationIdentifier: "\(telegramMessage.id.peerId.toInt64())", content: telegramMessage.text, dateSent: date, sender: sender, recipients: [], groupName: nil, messageType: messageType)
|
message = INMessage(identifier: identifier, conversationIdentifier: "\(telegramMessage.id.peerId.toInt64())", content: telegramMessage.text, dateSent: date, sender: sender, recipients: [], groupName: nil, messageType: messageType)
|
||||||
} else {
|
} else {
|
||||||
|
if telegramMessage.text.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
message = INMessage(identifier: identifier, content: telegramMessage.text, dateSent: date, sender: sender, recipients: [])
|
message = INMessage(identifier: identifier, content: telegramMessage.text, dateSent: date, sender: sender, recipients: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1304,7 +1304,10 @@ public class Account {
|
|||||||
self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedSynchronizeAppLogEventsOperations(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedSynchronizeAppLogEventsOperations(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedNotificationSettingsBehaviors(postbox: self.postbox).start())
|
self.managedOperationsDisposable.add(managedNotificationSettingsBehaviors(postbox: self.postbox).start())
|
||||||
self.managedOperationsDisposable.add(managedAnimatedEmojiUpdates(postbox: self.postbox, network: self.network).start())
|
|
||||||
|
if !self.supplementary {
|
||||||
|
self.managedOperationsDisposable.add(managedAnimatedEmojiUpdates(postbox: self.postbox, network: self.network).start())
|
||||||
|
}
|
||||||
|
|
||||||
let mediaBox = postbox.mediaBox
|
let mediaBox = postbox.mediaBox
|
||||||
self.storageSettingsDisposable = accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]).start(next: { [weak mediaBox] sharedData in
|
self.storageSettingsDisposable = accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]).start(next: { [weak mediaBox] sharedData in
|
||||||
|
@ -16,11 +16,27 @@ public func isViablePhoneNumber(_ string: String) -> Bool {
|
|||||||
return phoneNumberUtil.isViablePhoneNumber(string)
|
return phoneNumberUtil.isViablePhoneNumber(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func arePhoneNumbersEqual(_ lhs: String, _ rhs: String) -> Bool {
|
public class ParsedPhoneNumber: Equatable {
|
||||||
let result = phoneNumberUtil.isNumberMatch(lhs as NSString, second: rhs as NSString, error: nil)
|
let rawPhoneNumber: NBPhoneNumber?
|
||||||
if result != .NO_MATCH && result != .NOT_A_NUMBER {
|
|
||||||
return true
|
public init?(string: String) {
|
||||||
} else {
|
if let number = try? phoneNumberUtil.parse(string, defaultRegion: NB_UNKNOWN_REGION) {
|
||||||
return false
|
self.rawPhoneNumber = number
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: ParsedPhoneNumber, rhs: ParsedPhoneNumber) -> Bool {
|
||||||
|
var error: NSError?
|
||||||
|
let result = phoneNumberUtil.isNumberMatch(lhs.rawPhoneNumber, second: rhs.rawPhoneNumber, error: &error)
|
||||||
|
if error != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if result != .NO_MATCH && result != .NOT_A_NUMBER {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,12 +679,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
hapticFeedback.impact(.heavy)
|
hapticFeedback.impact(.heavy)
|
||||||
Queue.mainQueue().after(0.2) {
|
Queue.mainQueue().after(0.2) {
|
||||||
hapticFeedback.impact(.medium)
|
hapticFeedback.impact(.medium)
|
||||||
Queue.mainQueue().after(0.74) {
|
Queue.mainQueue().after(0.78) {
|
||||||
hapticFeedback.impact(.medium)
|
hapticFeedback.impact(.heavy)
|
||||||
Queue.mainQueue().after(0.2) {
|
Queue.mainQueue().after(0.2) {
|
||||||
hapticFeedback.impact(.medium)
|
hapticFeedback.impact(.medium)
|
||||||
Queue.mainQueue().after(0.74) {
|
Queue.mainQueue().after(0.78) {
|
||||||
hapticFeedback.impact(.medium)
|
hapticFeedback.impact(.heavy)
|
||||||
Queue.mainQueue().after(0.2) {
|
Queue.mainQueue().after(0.2) {
|
||||||
hapticFeedback.impact(.medium)
|
hapticFeedback.impact(.medium)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user