mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 03:40:18 +00:00
Fixed unread counter category for private channels
Added support for "contact joined" service messages Updated password recovery API Updated Localization APIs Added limited contact presence polling after getDifference
This commit is contained in:
parent
bf8ec5775f
commit
0b96d69daa
@ -366,6 +366,8 @@
|
|||||||
D05A32E51E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */; };
|
D05A32E51E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */; };
|
||||||
D05A32E71E6F0B5C002760B4 /* RecentAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */; };
|
D05A32E71E6F0B5C002760B4 /* RecentAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */; };
|
||||||
D05A32E81E6F0B5C002760B4 /* RecentAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */; };
|
D05A32E81E6F0B5C002760B4 /* RecentAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */; };
|
||||||
|
D05D8B372192F8AF0064586F /* LocalizationListState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05D8B362192F8AF0064586F /* LocalizationListState.swift */; };
|
||||||
|
D05D8B382192F8AF0064586F /* LocalizationListState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05D8B362192F8AF0064586F /* LocalizationListState.swift */; };
|
||||||
D0613FCA1E60440600202CDB /* InvitationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FC91E60440600202CDB /* InvitationLinks.swift */; };
|
D0613FCA1E60440600202CDB /* InvitationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FC91E60440600202CDB /* InvitationLinks.swift */; };
|
||||||
D0613FCB1E60440600202CDB /* InvitationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FC91E60440600202CDB /* InvitationLinks.swift */; };
|
D0613FCB1E60440600202CDB /* InvitationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FC91E60440600202CDB /* InvitationLinks.swift */; };
|
||||||
D0613FCF1E60520700202CDB /* ChannelMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FCE1E60520700202CDB /* ChannelMembers.swift */; };
|
D0613FCF1E60520700202CDB /* ChannelMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FCE1E60520700202CDB /* ChannelMembers.swift */; };
|
||||||
@ -957,6 +959,7 @@
|
|||||||
D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatedAccountPrivacySettings.swift; sourceTree = "<group>"; };
|
D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatedAccountPrivacySettings.swift; sourceTree = "<group>"; };
|
||||||
D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSessions.swift; sourceTree = "<group>"; };
|
D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSessions.swift; sourceTree = "<group>"; };
|
||||||
D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSession.swift; sourceTree = "<group>"; };
|
D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSession.swift; sourceTree = "<group>"; };
|
||||||
|
D05D8B362192F8AF0064586F /* LocalizationListState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationListState.swift; sourceTree = "<group>"; };
|
||||||
D0613FC91E60440600202CDB /* InvitationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvitationLinks.swift; sourceTree = "<group>"; };
|
D0613FC91E60440600202CDB /* InvitationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvitationLinks.swift; sourceTree = "<group>"; };
|
||||||
D0613FCE1E60520700202CDB /* ChannelMembers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelMembers.swift; sourceTree = "<group>"; };
|
D0613FCE1E60520700202CDB /* ChannelMembers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelMembers.swift; sourceTree = "<group>"; };
|
||||||
D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvertGroupToSupergroup.swift; sourceTree = "<group>"; };
|
D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvertGroupToSupergroup.swift; sourceTree = "<group>"; };
|
||||||
@ -1680,6 +1683,7 @@
|
|||||||
D08CAA7F1ED80ED20000FDA8 /* SuggestedLocalizationEntry.swift */,
|
D08CAA7F1ED80ED20000FDA8 /* SuggestedLocalizationEntry.swift */,
|
||||||
D08CAA831ED8164B0000FDA8 /* Localization.swift */,
|
D08CAA831ED8164B0000FDA8 /* Localization.swift */,
|
||||||
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */,
|
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */,
|
||||||
|
D05D8B362192F8AF0064586F /* LocalizationListState.swift */,
|
||||||
);
|
);
|
||||||
name = Localization;
|
name = Localization;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2179,6 +2183,7 @@
|
|||||||
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */,
|
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */,
|
||||||
D00C7CEB1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
|
D00C7CEB1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
|
||||||
D09BB6B61DB0428000A905C0 /* PendingMessageUploadedContent.swift in Sources */,
|
D09BB6B61DB0428000A905C0 /* PendingMessageUploadedContent.swift in Sources */,
|
||||||
|
D05D8B372192F8AF0064586F /* LocalizationListState.swift in Sources */,
|
||||||
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */,
|
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */,
|
||||||
D0B843B71DA7FF30005F29E1 /* NBMetadataCoreMapper.m in Sources */,
|
D0B843B71DA7FF30005F29E1 /* NBMetadataCoreMapper.m in Sources */,
|
||||||
D0AB0B921D65E9FA002C78E7 /* ManagedServiceViews.swift in Sources */,
|
D0AB0B921D65E9FA002C78E7 /* ManagedServiceViews.swift in Sources */,
|
||||||
@ -2716,6 +2721,7 @@
|
|||||||
D07047BB1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
|
D07047BB1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
|
||||||
D0380DBB204EF306000414AB /* MessageMediaPreuploadManager.swift in Sources */,
|
D0380DBB204EF306000414AB /* MessageMediaPreuploadManager.swift in Sources */,
|
||||||
D050F2621E4A5AE700988324 /* GlobalNotificationSettings.swift in Sources */,
|
D050F2621E4A5AE700988324 /* GlobalNotificationSettings.swift in Sources */,
|
||||||
|
D05D8B382192F8AF0064586F /* LocalizationListState.swift in Sources */,
|
||||||
D0DFD5E01FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
|
D0DFD5E01FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
|
||||||
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
|
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
|
||||||
D0E8174A2010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */,
|
D0E8174A2010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */,
|
||||||
|
|||||||
@ -185,10 +185,14 @@ let telegramPostboxSeedConfiguration: SeedConfiguration = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return SeedConfiguration(initializeChatListWithHole: (topLevel: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: Int32.max - 1)), groups: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: 1))), initializeMessageNamespacesWithHoles: initializeMessageNamespacesWithHoles, existingMessageTags: MessageTags.all, messageTagsWithSummary: MessageTags.unseenPersonalMessage, existingGlobalMessageTags: GlobalMessageTags.all, peerNamespacesRequiringMessageTextIndex: [Namespaces.Peer.SecretChat], peerSummaryCounterTags: { peer in
|
return SeedConfiguration(initializeChatListWithHole: (topLevel: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: Int32.max - 1)), groups: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: 1))), initializeMessageNamespacesWithHoles: initializeMessageNamespacesWithHoles, existingMessageTags: MessageTags.all, messageTagsWithSummary: MessageTags.unseenPersonalMessage, existingGlobalMessageTags: GlobalMessageTags.all, peerNamespacesRequiringMessageTextIndex: [Namespaces.Peer.SecretChat], peerSummaryCounterTags: { peer in
|
||||||
if let peer = peer as? TelegramChannel, let addressName = peer.addressName, !addressName.isEmpty {
|
if let peer = peer as? TelegramChannel {
|
||||||
switch peer.info {
|
switch peer.info {
|
||||||
case .group:
|
case .group:
|
||||||
|
if let addressName = peer.addressName, !addressName.isEmpty {
|
||||||
return [.publicGroups]
|
return [.publicGroups]
|
||||||
|
} else {
|
||||||
|
return [.regularChatsAndPrivateGroups]
|
||||||
|
}
|
||||||
case .broadcast:
|
case .broadcast:
|
||||||
return [.channels]
|
return [.channels]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,6 +89,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
|
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
|
||||||
declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
|
declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
|
||||||
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
|
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
|
||||||
|
declareEncodable(LocalizationListState.self, f: { LocalizationListState(decoder: $0) })
|
||||||
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
|
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
|
||||||
declareEncodable(NetworkSettings.self, f: { NetworkSettings(decoder: $0) })
|
declareEncodable(NetworkSettings.self, f: { NetworkSettings(decoder: $0) })
|
||||||
declareEncodable(RemoteStorageConfiguration.self, f: { RemoteStorageConfiguration(decoder: $0) })
|
declareEncodable(RemoteStorageConfiguration.self, f: { RemoteStorageConfiguration(decoder: $0) })
|
||||||
@ -242,9 +243,7 @@ public func currentAccount(allocateIfNotExists: Bool, networkArguments: NetworkI
|
|||||||
public func logoutFromAccount(id: AccountRecordId, accountManager: AccountManager) -> Signal<Void, NoError> {
|
public func logoutFromAccount(id: AccountRecordId, accountManager: AccountManager) -> Signal<Void, NoError> {
|
||||||
Logger.shared.log("AccountManager", "logoutFromAccount \(id)")
|
Logger.shared.log("AccountManager", "logoutFromAccount \(id)")
|
||||||
return accountManager.transaction { transaction -> Void in
|
return accountManager.transaction { transaction -> Void in
|
||||||
let currentId = transaction.getCurrentId()
|
transaction.updateRecord(id, { current in
|
||||||
if let currentId = currentId {
|
|
||||||
transaction.updateRecord(currentId, { current in
|
|
||||||
if let current = current {
|
if let current = current {
|
||||||
var found = false
|
var found = false
|
||||||
for attribute in current.attributes {
|
for attribute in current.attributes {
|
||||||
@ -262,8 +261,9 @@ public func logoutFromAccount(id: AccountRecordId, accountManager: AccountManage
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let id = transaction.createRecord([])
|
if transaction.getCurrentId() == id {
|
||||||
transaction.setCurrentId(id)
|
let updatedId = transaction.createRecord([])
|
||||||
|
transaction.setCurrentId(updatedId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,14 +285,15 @@ public func managedCleanupAccounts(networkArguments: NetworkInitializationArgume
|
|||||||
var disposeList: [(AccountRecordId, MetaDisposable)] = []
|
var disposeList: [(AccountRecordId, MetaDisposable)] = []
|
||||||
var beginList: [(AccountRecordId, MetaDisposable)] = []
|
var beginList: [(AccountRecordId, MetaDisposable)] = []
|
||||||
let _ = loggedOutAccounts.modify { disposables in
|
let _ = loggedOutAccounts.modify { disposables in
|
||||||
let validIds = Set(view.records.filter {
|
var validIds = Set<AccountRecordId>()
|
||||||
for attribute in $0.attributes {
|
outer: for record in view.records {
|
||||||
|
for attribute in record.attributes {
|
||||||
if attribute is LoggedOutAccountAttribute {
|
if attribute is LoggedOutAccountAttribute {
|
||||||
return true
|
validIds.insert(record.id)
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}.map { $0.id })
|
|
||||||
|
|
||||||
var disposables = disposables
|
var disposables = disposables
|
||||||
|
|
||||||
@ -320,7 +321,7 @@ public func managedCleanupAccounts(networkArguments: NetworkInitializationArgume
|
|||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
}
|
}
|
||||||
for (id, disposable) in beginList {
|
for (id, disposable) in beginList {
|
||||||
Logger.shared.log("managedCleanupAccounts", "cleanup \(id)")
|
Logger.shared.log("managedCleanupAccounts", "cleanup \(id), current is \(String(describing: view.currentRecord?.id))")
|
||||||
disposable.set(cleanupAccount(networkArguments: networkArguments, accountManager: accountManager, id: id, rootPath: rootPath, auxiliaryMethods: auxiliaryMethods).start())
|
disposable.set(cleanupAccount(networkArguments: networkArguments, accountManager: accountManager, id: id, rootPath: rootPath, auxiliaryMethods: auxiliaryMethods).start())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,13 +101,6 @@ private func locallyGeneratedMessageTimestampsFromUpdateGroups(_ groups: [Update
|
|||||||
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .updateContactRegistered(userId, date):
|
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
|
||||||
if messageTimestamps[peerId] == nil {
|
|
||||||
messageTimestamps[peerId] = [(Namespaces.Message.Local, date)]
|
|
||||||
} else {
|
|
||||||
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -306,13 +299,6 @@ private func locallyGeneratedMessageTimestampsFromDifference(_ difference: Api.u
|
|||||||
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .updateContactRegistered(userId, date):
|
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
|
||||||
if messageTimestamps[peerId] == nil {
|
|
||||||
messageTimestamps[peerId] = [(Namespaces.Message.Local, date)]
|
|
||||||
} else {
|
|
||||||
messageTimestamps[peerId]!.append((Namespaces.Message.Local, date))
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -920,25 +906,6 @@ private func finalStateWithUpdatesAndServerTime(account: Account, state: Account
|
|||||||
} else {
|
} else {
|
||||||
updatedState.addDisplayAlert(text)
|
updatedState.addDisplayAlert(text)
|
||||||
}
|
}
|
||||||
case let .updateContactRegistered(userId, date):
|
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
|
||||||
|
|
||||||
var alreadyStored = false
|
|
||||||
if let storedMessages = updatedState.storedMessagesByPeerIdAndTimestamp[peerId] {
|
|
||||||
for index in storedMessages {
|
|
||||||
if index.timestamp == date {
|
|
||||||
alreadyStored = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if alreadyStored {
|
|
||||||
Logger.shared.log("State", "skipping joined message at \(date) for \(peerId): already stored")
|
|
||||||
} else {
|
|
||||||
let message = StoreMessage(peerId: peerId, namespace: Namespaces.Message.Local, globallyUniqueId: nil, groupingKey: nil, timestamp: date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, authorId: peerId, text: "", attributes: [], media: [TelegramMediaAction(action: .peerJoined)])
|
|
||||||
updatedState.addMessages([message], location: .UpperHistoryBlock)
|
|
||||||
}
|
|
||||||
case let .updateReadChannelInbox(channelId, maxId):
|
case let .updateReadChannelInbox(channelId, maxId):
|
||||||
updatedState.readInbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId))
|
updatedState.readInbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId))
|
||||||
case let .updateReadChannelOutbox(channelId, maxId):
|
case let .updateReadChannelOutbox(channelId, maxId):
|
||||||
|
|||||||
@ -110,6 +110,11 @@ public final class AccountStateManager {
|
|||||||
return self.appliedIncomingReadMessagesPipe.signal()
|
return self.appliedIncomingReadMessagesPipe.signal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let significantStateUpdateCompletedPipe = ValuePipe<Void>()
|
||||||
|
var significantStateUpdateCompleted: Signal<Void, NoError> {
|
||||||
|
return self.significantStateUpdateCompletedPipe.signal()
|
||||||
|
}
|
||||||
|
|
||||||
private var updatedWebpageContexts: [MediaId: UpdatedWebpageSubscriberContext] = [:]
|
private var updatedWebpageContexts: [MediaId: UpdatedWebpageSubscriberContext] = [:]
|
||||||
|
|
||||||
private let delayNotificatonsUntil = Atomic<Int32?>(value: nil)
|
private let delayNotificatonsUntil = Atomic<Int32?>(value: nil)
|
||||||
@ -424,6 +429,7 @@ public final class AccountStateManager {
|
|||||||
strongSelf.insertProcessEvents(events)
|
strongSelf.insertProcessEvents(events)
|
||||||
}
|
}
|
||||||
strongSelf.currentIsUpdatingValue = false
|
strongSelf.currentIsUpdatingValue = false
|
||||||
|
strongSelf.significantStateUpdateCompletedPipe.putNext(Void())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !events.isEmpty {
|
if !events.isEmpty {
|
||||||
|
|||||||
@ -89,7 +89,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
|
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
|
||||||
dict[414687501] = { return Api.DcOption.parse_dcOption($0) }
|
dict[414687501] = { return Api.DcOption.parse_dcOption($0) }
|
||||||
dict[-1705233435] = { return Api.account.PasswordSettings.parse_passwordSettings($0) }
|
dict[-1705233435] = { return Api.account.PasswordSettings.parse_passwordSettings($0) }
|
||||||
dict[106019213] = { return Api.LangPackLanguage.parse_langPackLanguage($0) }
|
dict[-288727837] = { return Api.LangPackLanguage.parse_langPackLanguage($0) }
|
||||||
dict[-1987579119] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
dict[-1987579119] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
||||||
dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) }
|
dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) }
|
||||||
dict[-209337866] = { return Api.LangPackDifference.parse_langPackDifference($0) }
|
dict[-209337866] = { return Api.LangPackDifference.parse_langPackDifference($0) }
|
||||||
@ -154,7 +154,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[469489699] = { return Api.Update.parse_updateUserStatus($0) }
|
dict[469489699] = { return Api.Update.parse_updateUserStatus($0) }
|
||||||
dict[-1489818765] = { return Api.Update.parse_updateUserName($0) }
|
dict[-1489818765] = { return Api.Update.parse_updateUserName($0) }
|
||||||
dict[-1791935732] = { return Api.Update.parse_updateUserPhoto($0) }
|
dict[-1791935732] = { return Api.Update.parse_updateUserPhoto($0) }
|
||||||
dict[628472761] = { return Api.Update.parse_updateContactRegistered($0) }
|
|
||||||
dict[-1657903163] = { return Api.Update.parse_updateContactLink($0) }
|
dict[-1657903163] = { return Api.Update.parse_updateContactLink($0) }
|
||||||
dict[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($0) }
|
dict[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($0) }
|
||||||
dict[386986326] = { return Api.Update.parse_updateEncryptedChatTyping($0) }
|
dict[386986326] = { return Api.Update.parse_updateEncryptedChatTyping($0) }
|
||||||
@ -631,6 +630,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1410748418] = { return Api.MessageAction.parse_messageActionBotAllowed($0) }
|
dict[-1410748418] = { return Api.MessageAction.parse_messageActionBotAllowed($0) }
|
||||||
dict[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($0) }
|
dict[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($0) }
|
||||||
dict[-648257196] = { return Api.MessageAction.parse_messageActionSecureValuesSent($0) }
|
dict[-648257196] = { return Api.MessageAction.parse_messageActionSecureValuesSent($0) }
|
||||||
|
dict[1894744724] = { return Api.MessageAction.parse_messageActionContactSignUp($0) }
|
||||||
dict[1399245077] = { return Api.PhoneCall.parse_phoneCallEmpty($0) }
|
dict[1399245077] = { return Api.PhoneCall.parse_phoneCallEmpty($0) }
|
||||||
dict[462375633] = { return Api.PhoneCall.parse_phoneCallWaiting($0) }
|
dict[462375633] = { return Api.PhoneCall.parse_phoneCallWaiting($0) }
|
||||||
dict[-2089411356] = { return Api.PhoneCall.parse_phoneCallRequested($0) }
|
dict[-2089411356] = { return Api.PhoneCall.parse_phoneCallRequested($0) }
|
||||||
@ -651,7 +651,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[1889961234] = { return Api.PeerNotifySettings.parse_peerNotifySettingsEmpty($0) }
|
dict[1889961234] = { return Api.PeerNotifySettings.parse_peerNotifySettingsEmpty($0) }
|
||||||
dict[-1353671392] = { return Api.PeerNotifySettings.parse_peerNotifySettings($0) }
|
dict[-1353671392] = { return Api.PeerNotifySettings.parse_peerNotifySettings($0) }
|
||||||
dict[-1995686519] = { return Api.InputBotInlineMessageID.parse_inputBotInlineMessageID($0) }
|
dict[-1995686519] = { return Api.InputBotInlineMessageID.parse_inputBotInlineMessageID($0) }
|
||||||
dict[-242812612] = { return Api.PageRelatedArticle.parse_pageRelatedArticle($0) }
|
dict[-1282352120] = { return Api.PageRelatedArticle.parse_pageRelatedArticle($0) }
|
||||||
dict[313694676] = { return Api.StickerPack.parse_stickerPack($0) }
|
dict[313694676] = { return Api.StickerPack.parse_stickerPack($0) }
|
||||||
dict[1326562017] = { return Api.UserProfilePhoto.parse_userProfilePhotoEmpty($0) }
|
dict[1326562017] = { return Api.UserProfilePhoto.parse_userProfilePhotoEmpty($0) }
|
||||||
dict[-715532088] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
|
dict[-715532088] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
|
||||||
|
|||||||
@ -2362,13 +2362,13 @@ extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
enum LangPackLanguage: TypeConstructorDescription {
|
enum LangPackLanguage: TypeConstructorDescription {
|
||||||
case langPackLanguage(flags: Int32, name: String, nativeName: String, langCode: String, baseLangCode: String?, pluralCode: String, stringsCount: Int32, translatedCount: Int32)
|
case langPackLanguage(flags: Int32, name: String, nativeName: String, langCode: String, baseLangCode: String?, pluralCode: String, stringsCount: Int32, translatedCount: Int32, translationsUrl: String)
|
||||||
|
|
||||||
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount):
|
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount, let translationsUrl):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(106019213)
|
buffer.appendInt32(-288727837)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeString(name, buffer: buffer, boxed: false)
|
serializeString(name, buffer: buffer, boxed: false)
|
||||||
@ -2378,14 +2378,15 @@ extension Api {
|
|||||||
serializeString(pluralCode, buffer: buffer, boxed: false)
|
serializeString(pluralCode, buffer: buffer, boxed: false)
|
||||||
serializeInt32(stringsCount, buffer: buffer, boxed: false)
|
serializeInt32(stringsCount, buffer: buffer, boxed: false)
|
||||||
serializeInt32(translatedCount, buffer: buffer, boxed: false)
|
serializeInt32(translatedCount, buffer: buffer, boxed: false)
|
||||||
|
serializeString(translationsUrl, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func descriptionFields() -> (String, [(String, Any)]) {
|
func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount):
|
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount, let translationsUrl):
|
||||||
return ("langPackLanguage", [("flags", flags), ("name", name), ("nativeName", nativeName), ("langCode", langCode), ("baseLangCode", baseLangCode), ("pluralCode", pluralCode), ("stringsCount", stringsCount), ("translatedCount", translatedCount)])
|
return ("langPackLanguage", [("flags", flags), ("name", name), ("nativeName", nativeName), ("langCode", langCode), ("baseLangCode", baseLangCode), ("pluralCode", pluralCode), ("stringsCount", stringsCount), ("translatedCount", translatedCount), ("translationsUrl", translationsUrl)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2406,6 +2407,8 @@ extension Api {
|
|||||||
_7 = reader.readInt32()
|
_7 = reader.readInt32()
|
||||||
var _8: Int32?
|
var _8: Int32?
|
||||||
_8 = reader.readInt32()
|
_8 = reader.readInt32()
|
||||||
|
var _9: String?
|
||||||
|
_9 = parseString(reader)
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -2414,8 +2417,9 @@ extension Api {
|
|||||||
let _c6 = _6 != nil
|
let _c6 = _6 != nil
|
||||||
let _c7 = _7 != nil
|
let _c7 = _7 != nil
|
||||||
let _c8 = _8 != nil
|
let _c8 = _8 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
let _c9 = _9 != nil
|
||||||
return Api.LangPackLanguage.langPackLanguage(flags: _1!, name: _2!, nativeName: _3!, langCode: _4!, baseLangCode: _5, pluralCode: _6!, stringsCount: _7!, translatedCount: _8!)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||||
|
return Api.LangPackLanguage.langPackLanguage(flags: _1!, name: _2!, nativeName: _3!, langCode: _4!, baseLangCode: _5, pluralCode: _6!, stringsCount: _7!, translatedCount: _8!, translationsUrl: _9!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -3337,7 +3341,6 @@ extension Api {
|
|||||||
case updateUserStatus(userId: Int32, status: Api.UserStatus)
|
case updateUserStatus(userId: Int32, status: Api.UserStatus)
|
||||||
case updateUserName(userId: Int32, firstName: String, lastName: String, username: String)
|
case updateUserName(userId: Int32, firstName: String, lastName: String, username: String)
|
||||||
case updateUserPhoto(userId: Int32, date: Int32, photo: Api.UserProfilePhoto, previous: Api.Bool)
|
case updateUserPhoto(userId: Int32, date: Int32, photo: Api.UserProfilePhoto, previous: Api.Bool)
|
||||||
case updateContactRegistered(userId: Int32, date: Int32)
|
|
||||||
case updateContactLink(userId: Int32, myLink: Api.ContactLink, foreignLink: Api.ContactLink)
|
case updateContactLink(userId: Int32, myLink: Api.ContactLink, foreignLink: Api.ContactLink)
|
||||||
case updateNewEncryptedMessage(message: Api.EncryptedMessage, qts: Int32)
|
case updateNewEncryptedMessage(message: Api.EncryptedMessage, qts: Int32)
|
||||||
case updateEncryptedChatTyping(chatId: Int32)
|
case updateEncryptedChatTyping(chatId: Int32)
|
||||||
@ -3473,13 +3476,6 @@ extension Api {
|
|||||||
photo.serialize(buffer, true)
|
photo.serialize(buffer, true)
|
||||||
previous.serialize(buffer, true)
|
previous.serialize(buffer, true)
|
||||||
break
|
break
|
||||||
case .updateContactRegistered(let userId, let date):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(628472761)
|
|
||||||
}
|
|
||||||
serializeInt32(userId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .updateContactLink(let userId, let myLink, let foreignLink):
|
case .updateContactLink(let userId, let myLink, let foreignLink):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1657903163)
|
buffer.appendInt32(-1657903163)
|
||||||
@ -3988,8 +3984,6 @@ extension Api {
|
|||||||
return ("updateUserName", [("userId", userId), ("firstName", firstName), ("lastName", lastName), ("username", username)])
|
return ("updateUserName", [("userId", userId), ("firstName", firstName), ("lastName", lastName), ("username", username)])
|
||||||
case .updateUserPhoto(let userId, let date, let photo, let previous):
|
case .updateUserPhoto(let userId, let date, let photo, let previous):
|
||||||
return ("updateUserPhoto", [("userId", userId), ("date", date), ("photo", photo), ("previous", previous)])
|
return ("updateUserPhoto", [("userId", userId), ("date", date), ("photo", photo), ("previous", previous)])
|
||||||
case .updateContactRegistered(let userId, let date):
|
|
||||||
return ("updateContactRegistered", [("userId", userId), ("date", date)])
|
|
||||||
case .updateContactLink(let userId, let myLink, let foreignLink):
|
case .updateContactLink(let userId, let myLink, let foreignLink):
|
||||||
return ("updateContactLink", [("userId", userId), ("myLink", myLink), ("foreignLink", foreignLink)])
|
return ("updateContactLink", [("userId", userId), ("myLink", myLink), ("foreignLink", foreignLink)])
|
||||||
case .updateNewEncryptedMessage(let message, let qts):
|
case .updateNewEncryptedMessage(let message, let qts):
|
||||||
@ -4271,20 +4265,6 @@ extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static func parse_updateContactRegistered(_ reader: BufferReader) -> Update? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.Update.updateContactRegistered(userId: _1!, date: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static func parse_updateContactLink(_ reader: BufferReader) -> Update? {
|
static func parse_updateContactLink(_ reader: BufferReader) -> Update? {
|
||||||
var _1: Int32?
|
var _1: Int32?
|
||||||
_1 = reader.readInt32()
|
_1 = reader.readInt32()
|
||||||
@ -15158,6 +15138,7 @@ extension Api {
|
|||||||
case messageActionBotAllowed(domain: String)
|
case messageActionBotAllowed(domain: String)
|
||||||
case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted)
|
case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted)
|
||||||
case messageActionSecureValuesSent(types: [Api.SecureValueType])
|
case messageActionSecureValuesSent(types: [Api.SecureValueType])
|
||||||
|
case messageActionContactSignUp(flags: Int32)
|
||||||
|
|
||||||
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -15323,6 +15304,12 @@ extension Api {
|
|||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case .messageActionContactSignUp(let flags):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1894744724)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15372,6 +15359,8 @@ extension Api {
|
|||||||
return ("messageActionSecureValuesSentMe", [("values", values), ("credentials", credentials)])
|
return ("messageActionSecureValuesSentMe", [("values", values), ("credentials", credentials)])
|
||||||
case .messageActionSecureValuesSent(let types):
|
case .messageActionSecureValuesSent(let types):
|
||||||
return ("messageActionSecureValuesSent", [("types", types)])
|
return ("messageActionSecureValuesSent", [("types", types)])
|
||||||
|
case .messageActionContactSignUp(let flags):
|
||||||
|
return ("messageActionContactSignUp", [("flags", flags)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15637,6 +15626,17 @@ extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static func parse_messageActionContactSignUp(_ reader: BufferReader) -> MessageAction? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.MessageAction.messageActionContactSignUp(flags: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
enum PhoneCall: TypeConstructorDescription {
|
enum PhoneCall: TypeConstructorDescription {
|
||||||
@ -16258,13 +16258,13 @@ extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
enum PageRelatedArticle: TypeConstructorDescription {
|
enum PageRelatedArticle: TypeConstructorDescription {
|
||||||
case pageRelatedArticle(flags: Int32, url: String, webpageId: Int64, title: String?, description: String?, photoId: Int64?)
|
case pageRelatedArticle(flags: Int32, url: String, webpageId: Int64, title: String?, description: String?, photoId: Int64?, author: String?, publishedDate: Int32?)
|
||||||
|
|
||||||
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .pageRelatedArticle(let flags, let url, let webpageId, let title, let description, let photoId):
|
case .pageRelatedArticle(let flags, let url, let webpageId, let title, let description, let photoId, let author, let publishedDate):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-242812612)
|
buffer.appendInt32(-1282352120)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
serializeString(url, buffer: buffer, boxed: false)
|
||||||
@ -16272,14 +16272,16 @@ extension Api {
|
|||||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(description!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(description!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt64(photoId!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt64(photoId!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {serializeString(author!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(publishedDate!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func descriptionFields() -> (String, [(String, Any)]) {
|
func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .pageRelatedArticle(let flags, let url, let webpageId, let title, let description, let photoId):
|
case .pageRelatedArticle(let flags, let url, let webpageId, let title, let description, let photoId, let author, let publishedDate):
|
||||||
return ("pageRelatedArticle", [("flags", flags), ("url", url), ("webpageId", webpageId), ("title", title), ("description", description), ("photoId", photoId)])
|
return ("pageRelatedArticle", [("flags", flags), ("url", url), ("webpageId", webpageId), ("title", title), ("description", description), ("photoId", photoId), ("author", author), ("publishedDate", publishedDate)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16296,14 +16298,20 @@ extension Api {
|
|||||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) }
|
if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) }
|
||||||
var _6: Int64?
|
var _6: Int64?
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {_6 = reader.readInt64() }
|
if Int(_1!) & Int(1 << 2) != 0 {_6 = reader.readInt64() }
|
||||||
|
var _7: String?
|
||||||
|
if Int(_1!) & Int(1 << 3) != 0 {_7 = parseString(reader) }
|
||||||
|
var _8: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 4) != 0 {_8 = reader.readInt32() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||||
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
|
||||||
return Api.PageRelatedArticle.pageRelatedArticle(flags: _1!, url: _2!, webpageId: _3!, title: _4, description: _5, photoId: _6)
|
let _c8 = (Int(_1!) & Int(1 << 4) == 0) || _8 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||||
|
return Api.PageRelatedArticle.pageRelatedArticle(flags: _1!, url: _2!, webpageId: _3!, title: _4, description: _5, photoId: _6, author: _7, publishedDate: _8)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -4939,12 +4939,53 @@ extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static func confirmPasswordEmail(email: String, code: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
static func confirmPasswordEmail(code: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(-558870880)
|
buffer.appendInt32(-1881204448)
|
||||||
serializeString(email, buffer: buffer, boxed: false)
|
|
||||||
serializeString(code, buffer: buffer, boxed: false)
|
serializeString(code, buffer: buffer, boxed: false)
|
||||||
return (FunctionDescription(name: "account.confirmPasswordEmail", parameters: [("email", email), ("code", code)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
return (FunctionDescription(name: "account.confirmPasswordEmail", parameters: [("code", code)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static func resendPasswordEmail() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(2055154197)
|
||||||
|
|
||||||
|
return (FunctionDescription(name: "account.resendPasswordEmail", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static func getContactSignUpNotification() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-1626880216)
|
||||||
|
|
||||||
|
return (FunctionDescription(name: "account.getContactSignUpNotification", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static func setContactSignUpNotification(silent: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-806076575)
|
||||||
|
silent.serialize(buffer, true)
|
||||||
|
return (FunctionDescription(name: "account.setContactSignUpNotification", parameters: [("silent", silent)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
let reader = BufferReader(buffer)
|
let reader = BufferReader(buffer)
|
||||||
var result: Api.Bool?
|
var result: Api.Bool?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
|
|||||||
@ -15,8 +15,8 @@ public enum ConfirmTwoStepRecoveryEmailError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func confirmTwoStepRecoveryEmail(network: Network, email: String, code: String) -> Signal<Never, ConfirmTwoStepRecoveryEmailError> {
|
public func confirmTwoStepRecoveryEmail(network: Network, code: String) -> Signal<Never, ConfirmTwoStepRecoveryEmailError> {
|
||||||
return network.request(Api.functions.account.confirmPasswordEmail(email: email, code: code), automaticFloodWait: false)
|
return network.request(Api.functions.account.confirmPasswordEmail(code: code), automaticFloodWait: false)
|
||||||
|> mapError { error -> ConfirmTwoStepRecoveryEmailError in
|
|> mapError { error -> ConfirmTwoStepRecoveryEmailError in
|
||||||
if error.errorDescription == "EMAIL_INVALID" {
|
if error.errorDescription == "EMAIL_INVALID" {
|
||||||
return .invalidEmail
|
return .invalidEmail
|
||||||
@ -31,3 +31,19 @@ public func confirmTwoStepRecoveryEmail(network: Network, email: String, code: S
|
|||||||
}
|
}
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ResendTwoStepRecoveryEmailError {
|
||||||
|
case flood
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
|
public func resendTwoStepRecoveryEmail(network: Network) -> Signal<Never, ResendTwoStepRecoveryEmailError> {
|
||||||
|
return network.request(Api.functions.account.resendPasswordEmail(), automaticFloodWait: false)
|
||||||
|
|> mapError { error -> ResendTwoStepRecoveryEmailError in
|
||||||
|
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||||
|
return .flood
|
||||||
|
}
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|||||||
@ -35,9 +35,11 @@ private final class ContactSyncManagerImpl {
|
|||||||
private var nextId: Int32 = 0
|
private var nextId: Int32 = 0
|
||||||
private var operations: [ContactSyncOperation] = []
|
private var operations: [ContactSyncOperation] = []
|
||||||
|
|
||||||
|
private var lastContactPresencesRequestTimestamp: Double?
|
||||||
private var reimportAttempts: [TelegramDeviceContactImportIdentifier: Double] = [:]
|
private var reimportAttempts: [TelegramDeviceContactImportIdentifier: Double] = [:]
|
||||||
|
|
||||||
private let importableContactsDisposable = MetaDisposable()
|
private let importableContactsDisposable = MetaDisposable()
|
||||||
|
private let significantStateUpdateCompletedDisposable = MetaDisposable()
|
||||||
|
|
||||||
init(queue: Queue, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager) {
|
init(queue: Queue, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
@ -61,6 +63,36 @@ private final class ContactSyncManagerImpl {
|
|||||||
strongSelf.addOperation(.updatePresences)
|
strongSelf.addOperation(.updatePresences)
|
||||||
strongSelf.addOperation(.sync(importableContacts: importableContacts))
|
strongSelf.addOperation(.sync(importableContacts: importableContacts))
|
||||||
}))
|
}))
|
||||||
|
self.significantStateUpdateCompletedDisposable.set((self.stateManager.significantStateUpdateCompleted
|
||||||
|
|> deliverOn(self.queue)).start(next: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let timestamp = CFAbsoluteTimeGetCurrent()
|
||||||
|
let shouldUpdate: Bool
|
||||||
|
if let lastContactPresencesRequestTimestamp = strongSelf.lastContactPresencesRequestTimestamp {
|
||||||
|
if timestamp > lastContactPresencesRequestTimestamp + 30.0 * 60.0 {
|
||||||
|
shouldUpdate = true
|
||||||
|
} else {
|
||||||
|
shouldUpdate = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shouldUpdate = true
|
||||||
|
}
|
||||||
|
if shouldUpdate {
|
||||||
|
strongSelf.lastContactPresencesRequestTimestamp = timestamp
|
||||||
|
var found = false
|
||||||
|
for operation in strongSelf.operations {
|
||||||
|
if case .updatePresences = operation.content {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
strongSelf.addOperation(.updatePresences)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func addIsContactUpdates(_ updates: [(PeerId, Bool)]) {
|
func addIsContactUpdates(_ updates: [(PeerId, Bool)]) {
|
||||||
|
|||||||
@ -950,7 +950,7 @@ extension InstantPageTableRow {
|
|||||||
extension InstantPageRelatedArticle {
|
extension InstantPageRelatedArticle {
|
||||||
convenience init(apiRelatedArticle: Api.PageRelatedArticle) {
|
convenience init(apiRelatedArticle: Api.PageRelatedArticle) {
|
||||||
switch apiRelatedArticle {
|
switch apiRelatedArticle {
|
||||||
case let .pageRelatedArticle(flags, url, webpageId, title, description, photoId):
|
case let .pageRelatedArticle(flags, url, webpageId, title, description, photoId, author, publishedDate):
|
||||||
var posterPhotoId: MediaId?
|
var posterPhotoId: MediaId?
|
||||||
if let photoId = photoId {
|
if let photoId = photoId {
|
||||||
posterPhotoId = MediaId(namespace: Namespaces.Media.CloudImage, id: photoId)
|
posterPhotoId = MediaId(namespace: Namespaces.Media.CloudImage, id: photoId)
|
||||||
|
|||||||
@ -5,20 +5,21 @@ import Foundation
|
|||||||
import Postbox
|
import Postbox
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public final class LimitsConfiguration: PreferencesEntry {
|
public struct LimitsConfiguration: Equatable, PreferencesEntry {
|
||||||
public let maxGroupMemberCount: Int32
|
public var maxGroupMemberCount: Int32
|
||||||
public let maxSupergroupMemberCount: Int32
|
public var maxSupergroupMemberCount: Int32
|
||||||
public let maxMessageForwardBatchSize: Int32
|
public var maxMessageForwardBatchSize: Int32
|
||||||
public let maxSavedGifCount: Int32
|
public var maxSavedGifCount: Int32
|
||||||
public let maxRecentStickerCount: Int32
|
public var maxRecentStickerCount: Int32
|
||||||
public let maxMessageEditingInterval: Int32
|
public var maxMessageEditingInterval: Int32
|
||||||
public let maxMediaCaptionLength: Int32
|
public var maxMediaCaptionLength: Int32
|
||||||
|
public var canRemoveIncomingMessagesInPrivateChats: Bool
|
||||||
|
|
||||||
public static var defaultValue: LimitsConfiguration {
|
public static var defaultValue: LimitsConfiguration {
|
||||||
return LimitsConfiguration(maxGroupMemberCount: 200, maxSupergroupMemberCount: 5000, maxMessageForwardBatchSize: 50, maxSavedGifCount: 200, maxRecentStickerCount: 20, maxMessageEditingInterval: 2 * 24 * 60 * 60, maxMediaCaptionLength: 1000)
|
return LimitsConfiguration(maxGroupMemberCount: 200, maxSupergroupMemberCount: 5000, maxMessageForwardBatchSize: 50, maxSavedGifCount: 200, maxRecentStickerCount: 20, maxMessageEditingInterval: 2 * 24 * 60 * 60, maxMediaCaptionLength: 1000, canRemoveIncomingMessagesInPrivateChats: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(maxGroupMemberCount: Int32, maxSupergroupMemberCount: Int32, maxMessageForwardBatchSize: Int32, maxSavedGifCount: Int32, maxRecentStickerCount: Int32, maxMessageEditingInterval: Int32, maxMediaCaptionLength: Int32) {
|
init(maxGroupMemberCount: Int32, maxSupergroupMemberCount: Int32, maxMessageForwardBatchSize: Int32, maxSavedGifCount: Int32, maxRecentStickerCount: Int32, maxMessageEditingInterval: Int32, maxMediaCaptionLength: Int32, canRemoveIncomingMessagesInPrivateChats: Bool) {
|
||||||
self.maxGroupMemberCount = maxGroupMemberCount
|
self.maxGroupMemberCount = maxGroupMemberCount
|
||||||
self.maxSupergroupMemberCount = maxSupergroupMemberCount
|
self.maxSupergroupMemberCount = maxSupergroupMemberCount
|
||||||
self.maxMessageForwardBatchSize = maxMessageForwardBatchSize
|
self.maxMessageForwardBatchSize = maxMessageForwardBatchSize
|
||||||
@ -26,6 +27,7 @@ public final class LimitsConfiguration: PreferencesEntry {
|
|||||||
self.maxRecentStickerCount = maxRecentStickerCount
|
self.maxRecentStickerCount = maxRecentStickerCount
|
||||||
self.maxMessageEditingInterval = maxMessageEditingInterval
|
self.maxMessageEditingInterval = maxMessageEditingInterval
|
||||||
self.maxMediaCaptionLength = maxMediaCaptionLength
|
self.maxMediaCaptionLength = maxMediaCaptionLength
|
||||||
|
self.canRemoveIncomingMessagesInPrivateChats = canRemoveIncomingMessagesInPrivateChats
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -36,6 +38,7 @@ public final class LimitsConfiguration: PreferencesEntry {
|
|||||||
self.maxRecentStickerCount = decoder.decodeInt32ForKey("maxRecentStickerCount", orElse: 20)
|
self.maxRecentStickerCount = decoder.decodeInt32ForKey("maxRecentStickerCount", orElse: 20)
|
||||||
self.maxMessageEditingInterval = decoder.decodeInt32ForKey("maxMessageEditingInterval", orElse: 2 * 24 * 60 * 60)
|
self.maxMessageEditingInterval = decoder.decodeInt32ForKey("maxMessageEditingInterval", orElse: 2 * 24 * 60 * 60)
|
||||||
self.maxMediaCaptionLength = decoder.decodeInt32ForKey("maxMediaCaptionLength", orElse: 1000)
|
self.maxMediaCaptionLength = decoder.decodeInt32ForKey("maxMediaCaptionLength", orElse: 1000)
|
||||||
|
self.canRemoveIncomingMessagesInPrivateChats = decoder.decodeInt32ForKey("canRemoveIncomingMessagesInPrivateChats", orElse: 0) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -46,34 +49,14 @@ public final class LimitsConfiguration: PreferencesEntry {
|
|||||||
encoder.encodeInt32(self.maxRecentStickerCount, forKey: "maxRecentStickerCount")
|
encoder.encodeInt32(self.maxRecentStickerCount, forKey: "maxRecentStickerCount")
|
||||||
encoder.encodeInt32(self.maxMessageEditingInterval, forKey: "maxMessageEditingInterval")
|
encoder.encodeInt32(self.maxMessageEditingInterval, forKey: "maxMessageEditingInterval")
|
||||||
encoder.encodeInt32(self.maxMediaCaptionLength, forKey: "maxMediaCaptionLength")
|
encoder.encodeInt32(self.maxMediaCaptionLength, forKey: "maxMediaCaptionLength")
|
||||||
|
encoder.encodeInt32(self.canRemoveIncomingMessagesInPrivateChats ? 1 : 0, forKey: "canRemoveIncomingMessagesInPrivateChats")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||||
guard let to = to as? LimitsConfiguration else {
|
guard let to = to as? LimitsConfiguration else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if self.maxGroupMemberCount != to.maxGroupMemberCount {
|
return self == to
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxSupergroupMemberCount != to.maxSupergroupMemberCount {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxMessageForwardBatchSize != to.maxMessageForwardBatchSize {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxSavedGifCount != to.maxSavedGifCount {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxRecentStickerCount != to.maxRecentStickerCount {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxMessageEditingInterval != to.maxMessageEditingInterval {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if self.maxMediaCaptionLength != to.maxMediaCaptionLength {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Foundation
|
|||||||
import Postbox
|
import Postbox
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public final class LocalizationInfo: PostboxCoding {
|
public struct LocalizationInfo: PostboxCoding, Equatable {
|
||||||
public let languageCode: String
|
public let languageCode: String
|
||||||
public let baseLanguageCode: String?
|
public let baseLanguageCode: String?
|
||||||
public let customPluralizationCode: String?
|
public let customPluralizationCode: String?
|
||||||
@ -14,8 +14,9 @@ public final class LocalizationInfo: PostboxCoding {
|
|||||||
public let isOfficial: Bool
|
public let isOfficial: Bool
|
||||||
public let totalStringCount: Int32
|
public let totalStringCount: Int32
|
||||||
public let translatedStringCount: Int32
|
public let translatedStringCount: Int32
|
||||||
|
public let platformUrl: String
|
||||||
|
|
||||||
public init(languageCode: String, baseLanguageCode: String?, customPluralizationCode: String?, title: String, localizedTitle: String, isOfficial: Bool, totalStringCount: Int32, translatedStringCount: Int32) {
|
public init(languageCode: String, baseLanguageCode: String?, customPluralizationCode: String?, title: String, localizedTitle: String, isOfficial: Bool, totalStringCount: Int32, translatedStringCount: Int32, platformUrl: String) {
|
||||||
self.languageCode = languageCode
|
self.languageCode = languageCode
|
||||||
self.baseLanguageCode = baseLanguageCode
|
self.baseLanguageCode = baseLanguageCode
|
||||||
self.customPluralizationCode = customPluralizationCode
|
self.customPluralizationCode = customPluralizationCode
|
||||||
@ -24,6 +25,7 @@ public final class LocalizationInfo: PostboxCoding {
|
|||||||
self.isOfficial = isOfficial
|
self.isOfficial = isOfficial
|
||||||
self.totalStringCount = totalStringCount
|
self.totalStringCount = totalStringCount
|
||||||
self.translatedStringCount = translatedStringCount
|
self.translatedStringCount = translatedStringCount
|
||||||
|
self.platformUrl = platformUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -35,6 +37,7 @@ public final class LocalizationInfo: PostboxCoding {
|
|||||||
self.isOfficial = decoder.decodeInt32ForKey("of", orElse: 0) != 0
|
self.isOfficial = decoder.decodeInt32ForKey("of", orElse: 0) != 0
|
||||||
self.totalStringCount = decoder.decodeInt32ForKey("tsc", orElse: 0)
|
self.totalStringCount = decoder.decodeInt32ForKey("tsc", orElse: 0)
|
||||||
self.translatedStringCount = decoder.decodeInt32ForKey("lsc", orElse: 0)
|
self.translatedStringCount = decoder.decodeInt32ForKey("lsc", orElse: 0)
|
||||||
|
self.platformUrl = decoder.decodeStringForKey("platformUrl", orElse: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -54,14 +57,15 @@ public final class LocalizationInfo: PostboxCoding {
|
|||||||
encoder.encodeInt32(self.isOfficial ? 1 : 0, forKey: "of")
|
encoder.encodeInt32(self.isOfficial ? 1 : 0, forKey: "of")
|
||||||
encoder.encodeInt32(self.totalStringCount, forKey: "tsc")
|
encoder.encodeInt32(self.totalStringCount, forKey: "tsc")
|
||||||
encoder.encodeInt32(self.translatedStringCount, forKey: "lsc")
|
encoder.encodeInt32(self.translatedStringCount, forKey: "lsc")
|
||||||
|
encoder.encodeString(self.platformUrl, forKey: "platformUrl")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension LocalizationInfo {
|
extension LocalizationInfo {
|
||||||
convenience init(apiLanguage: Api.LangPackLanguage) {
|
init(apiLanguage: Api.LangPackLanguage) {
|
||||||
switch apiLanguage {
|
switch apiLanguage {
|
||||||
case let .langPackLanguage(language):
|
case let .langPackLanguage(language):
|
||||||
self.init(languageCode: language.langCode, baseLanguageCode: language.baseLangCode, customPluralizationCode: language.pluralCode, title: language.name, localizedTitle: language.nativeName, isOfficial: (language.flags & (1 << 0)) != 0, totalStringCount: language.stringsCount, translatedStringCount: language.translatedCount)
|
self.init(languageCode: language.langCode, baseLanguageCode: language.baseLangCode, customPluralizationCode: language.pluralCode, title: language.name, localizedTitle: language.nativeName, isOfficial: (language.flags & (1 << 0)) != 0, totalStringCount: language.stringsCount, translatedStringCount: language.translatedCount, platformUrl: language.translationsUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
102
TelegramCore/LocalizationListState.swift
Normal file
102
TelegramCore/LocalizationListState.swift
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public struct LocalizationListState: PreferencesEntry, Equatable {
|
||||||
|
public var availableOfficialLocalizations: [LocalizationInfo]
|
||||||
|
public var availableSavedLocalizations: [LocalizationInfo]
|
||||||
|
|
||||||
|
public static var defaultSettings: LocalizationListState {
|
||||||
|
return LocalizationListState(availableOfficialLocalizations: [], availableSavedLocalizations: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(availableOfficialLocalizations: [LocalizationInfo], availableSavedLocalizations: [LocalizationInfo]) {
|
||||||
|
self.availableOfficialLocalizations = availableOfficialLocalizations
|
||||||
|
self.availableSavedLocalizations = availableSavedLocalizations
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
self.availableOfficialLocalizations = decoder.decodeObjectArrayWithDecoderForKey("availableOfficialLocalizations")
|
||||||
|
self.availableSavedLocalizations = decoder.decodeObjectArrayWithDecoderForKey("availableSavedLocalizations")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeObjectArray(self.availableOfficialLocalizations, forKey: "availableOfficialLocalizations")
|
||||||
|
encoder.encodeObjectArray(self.availableSavedLocalizations, forKey: "availableSavedLocalizations")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||||
|
guard let to = to as? LocalizationListState else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return self == to
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removeSavedLocalization(transaction: Transaction, languageCode: String) {
|
||||||
|
updateLocalizationListStateInteractively(transaction: transaction, { state in
|
||||||
|
var state = state
|
||||||
|
state.availableSavedLocalizations = state.availableSavedLocalizations.filter({ $0.languageCode != languageCode })
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLocalizationListStateInteractively(postbox: Postbox, _ f: @escaping (LocalizationListState) -> LocalizationListState) -> Signal<Void, NoError> {
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
updateLocalizationListStateInteractively(transaction: transaction, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLocalizationListStateInteractively(transaction: Transaction, _ f: @escaping (LocalizationListState) -> LocalizationListState) {
|
||||||
|
transaction.updatePreferencesEntry(key: PreferencesKeys.localizationListState, { current in
|
||||||
|
let previous = (current as? LocalizationListState) ?? LocalizationListState.defaultSettings
|
||||||
|
var updated = f(previous)
|
||||||
|
var removeOfficialIndices: [Int] = []
|
||||||
|
var officialSet = Set<String>()
|
||||||
|
for i in 0 ..< updated.availableOfficialLocalizations.count {
|
||||||
|
if officialSet.contains(updated.availableOfficialLocalizations[i].languageCode) {
|
||||||
|
removeOfficialIndices.append(i)
|
||||||
|
} else {
|
||||||
|
officialSet.insert(updated.availableOfficialLocalizations[i].languageCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in removeOfficialIndices.reversed() {
|
||||||
|
updated.availableOfficialLocalizations.remove(at: i)
|
||||||
|
}
|
||||||
|
var removeSavedIndices: [Int] = []
|
||||||
|
var savedSet = Set<String>()
|
||||||
|
for i in 0 ..< updated.availableSavedLocalizations.count {
|
||||||
|
if savedSet.contains(updated.availableSavedLocalizations[i].languageCode) {
|
||||||
|
removeSavedIndices.append(i)
|
||||||
|
} else {
|
||||||
|
savedSet.insert(updated.availableSavedLocalizations[i].languageCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in removeSavedIndices.reversed() {
|
||||||
|
updated.availableSavedLocalizations.remove(at: i)
|
||||||
|
}
|
||||||
|
return updated
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public func synchronizedLocalizationListState(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||||
|
return network.request(Api.functions.langpack.getLanguages(langPack: ""))
|
||||||
|
|> retryRequest
|
||||||
|
|> mapToSignal { languages -> Signal<Never, NoError> in
|
||||||
|
let infos: [LocalizationInfo] = languages.map(LocalizationInfo.init(apiLanguage:))
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
updateLocalizationListStateInteractively(transaction: transaction, { current in
|
||||||
|
var current = current
|
||||||
|
current.availableOfficialLocalizations = infos
|
||||||
|
return current
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,23 +7,27 @@ import Foundation
|
|||||||
|
|
||||||
public final class LocalizationComponent: Equatable, PostboxCoding {
|
public final class LocalizationComponent: Equatable, PostboxCoding {
|
||||||
public let languageCode: String
|
public let languageCode: String
|
||||||
|
public let localizedName: String
|
||||||
public let localization: Localization
|
public let localization: Localization
|
||||||
public let customPluralizationCode: String?
|
public let customPluralizationCode: String?
|
||||||
|
|
||||||
public init(languageCode: String, localization: Localization, customPluralizationCode: String?) {
|
public init(languageCode: String, localizedName: String, localization: Localization, customPluralizationCode: String?) {
|
||||||
self.languageCode = languageCode
|
self.languageCode = languageCode
|
||||||
|
self.localizedName = localizedName
|
||||||
self.localization = localization
|
self.localization = localization
|
||||||
self.customPluralizationCode = customPluralizationCode
|
self.customPluralizationCode = customPluralizationCode
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
self.languageCode = decoder.decodeStringForKey("lc", orElse: "")
|
self.languageCode = decoder.decodeStringForKey("lc", orElse: "")
|
||||||
|
self.localizedName = decoder.decodeStringForKey("localizedName", orElse: "")
|
||||||
self.localization = decoder.decodeObjectForKey("loc", decoder: { Localization(decoder: $0) }) as! Localization
|
self.localization = decoder.decodeObjectForKey("loc", decoder: { Localization(decoder: $0) }) as! Localization
|
||||||
self.customPluralizationCode = decoder.decodeOptionalStringForKey("cpl")
|
self.customPluralizationCode = decoder.decodeOptionalStringForKey("cpl")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
encoder.encodeString(self.languageCode, forKey: "lc")
|
encoder.encodeString(self.languageCode, forKey: "lc")
|
||||||
|
encoder.encodeString(self.localizedName, forKey: "localizedName")
|
||||||
encoder.encodeObject(self.localization, forKey: "loc")
|
encoder.encodeObject(self.localization, forKey: "loc")
|
||||||
if let customPluralizationCode = self.customPluralizationCode {
|
if let customPluralizationCode = self.customPluralizationCode {
|
||||||
encoder.encodeString(customPluralizationCode, forKey: "cpl")
|
encoder.encodeString(customPluralizationCode, forKey: "cpl")
|
||||||
@ -36,6 +40,9 @@ public final class LocalizationComponent: Equatable, PostboxCoding {
|
|||||||
if lhs.languageCode != rhs.languageCode {
|
if lhs.languageCode != rhs.languageCode {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.localizedName != rhs.localizedName {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.localization != rhs.localization {
|
if lhs.localization != rhs.localization {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -57,7 +64,7 @@ public final class LocalizationSettings: PreferencesEntry, Equatable {
|
|||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
if let languageCode = decoder.decodeOptionalStringForKey("lc") {
|
if let languageCode = decoder.decodeOptionalStringForKey("lc") {
|
||||||
self.primaryComponent = LocalizationComponent(languageCode: languageCode, localization: decoder.decodeObjectForKey("loc", decoder: { Localization(decoder: $0) }) as! Localization, customPluralizationCode: nil)
|
self.primaryComponent = LocalizationComponent(languageCode: languageCode, localizedName: "", localization: decoder.decodeObjectForKey("loc", decoder: { Localization(decoder: $0) }) as! Localization, customPluralizationCode: nil)
|
||||||
self.secondaryComponent = nil
|
self.secondaryComponent = nil
|
||||||
} else {
|
} else {
|
||||||
self.primaryComponent = decoder.decodeObjectForKey("primaryComponent", decoder: { LocalizationComponent(decoder: $0) }) as! LocalizationComponent
|
self.primaryComponent = decoder.decodeObjectForKey("primaryComponent", decoder: { LocalizationComponent(decoder: $0) }) as! LocalizationComponent
|
||||||
|
|||||||
@ -139,11 +139,23 @@ public func downloadAndApplyLocalization(postbox: Postbox, network: Network, lan
|
|||||||
}
|
}
|
||||||
var secondaryComponent: LocalizationComponent?
|
var secondaryComponent: LocalizationComponent?
|
||||||
if let secondaryCode = preview.baseLanguageCode, components.count > 1 {
|
if let secondaryCode = preview.baseLanguageCode, components.count > 1 {
|
||||||
secondaryComponent = LocalizationComponent(languageCode: secondaryCode, localization: components[1], customPluralizationCode: nil)
|
secondaryComponent = LocalizationComponent(languageCode: secondaryCode, localizedName: "", localization: components[1], customPluralizationCode: nil)
|
||||||
}
|
}
|
||||||
return postbox.transaction { transaction -> Signal<Void, DownloadAndApplyLocalizationError> in
|
return postbox.transaction { transaction -> Signal<Void, DownloadAndApplyLocalizationError> in
|
||||||
transaction.updatePreferencesEntry(key: PreferencesKeys.localizationSettings, { _ in
|
transaction.updatePreferencesEntry(key: PreferencesKeys.localizationSettings, { _ in
|
||||||
return LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: preview.languageCode, localization: primaryLocalization, customPluralizationCode: preview.customPluralizationCode), secondaryComponent: secondaryComponent)
|
return LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: preview.languageCode, localizedName: preview.localizedTitle, localization: primaryLocalization, customPluralizationCode: preview.customPluralizationCode), secondaryComponent: secondaryComponent)
|
||||||
|
})
|
||||||
|
|
||||||
|
updateLocalizationListStateInteractively(transaction: transaction, { state in
|
||||||
|
var state = state
|
||||||
|
for i in 0 ..< state.availableSavedLocalizations.count {
|
||||||
|
if state.availableSavedLocalizations[i].languageCode == preview.languageCode {
|
||||||
|
state.availableSavedLocalizations.remove(at: i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.availableSavedLocalizations.insert(preview, at: 0)
|
||||||
|
return state
|
||||||
})
|
})
|
||||||
|
|
||||||
network.context.updateApiEnvironment { current in
|
network.context.updateApiEnvironment { current in
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func managedConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<V
|
|||||||
return entry
|
return entry
|
||||||
})
|
})
|
||||||
|
|
||||||
updateLimitsConfiguration(transaction: transaction, configuration: LimitsConfiguration(maxGroupMemberCount: config.chatSizeMax, maxSupergroupMemberCount: config.megagroupSizeMax, maxMessageForwardBatchSize: config.forwardedCountMax, maxSavedGifCount: config.savedGifsLimit, maxRecentStickerCount: config.stickersRecentLimit, maxMessageEditingInterval: config.editTimeLimit, maxMediaCaptionLength: config.captionLengthMax))
|
updateLimitsConfiguration(transaction: transaction, configuration: LimitsConfiguration(maxGroupMemberCount: config.chatSizeMax, maxSupergroupMemberCount: config.megagroupSizeMax, maxMessageForwardBatchSize: config.forwardedCountMax, maxSavedGifCount: config.savedGifsLimit, maxRecentStickerCount: config.stickersRecentLimit, maxMessageEditingInterval: config.editTimeLimit, maxMediaCaptionLength: config.captionLengthMax, canRemoveIncomingMessagesInPrivateChats: (config.flags & (1 << 6)) != 0))
|
||||||
|
|
||||||
let (primary, secondary) = getLocalization(transaction)
|
let (primary, secondary) = getLocalization(transaction)
|
||||||
var invalidateLocalization = false
|
var invalidateLocalization = false
|
||||||
|
|||||||
@ -174,7 +174,7 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
|
|||||||
return postbox.transaction { transaction -> Signal<Void, SynchronizeLocalizationUpdatesError> in
|
return postbox.transaction { transaction -> Signal<Void, SynchronizeLocalizationUpdatesError> in
|
||||||
let (primary, secondary) = getLocalization(transaction)
|
let (primary, secondary) = getLocalization(transaction)
|
||||||
|
|
||||||
var currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
|
var currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
|
||||||
|
|
||||||
for difference in parsedDifferences {
|
for difference in parsedDifferences {
|
||||||
let current: (isPrimary: Bool, entries: [LocalizationEntry])
|
let current: (isPrimary: Bool, entries: [LocalizationEntry])
|
||||||
@ -205,9 +205,9 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
|
|||||||
}
|
}
|
||||||
mergedEntries.append(contentsOf: difference.entries)
|
mergedEntries.append(contentsOf: difference.entries)
|
||||||
if current.isPrimary {
|
if current.isPrimary {
|
||||||
currentSettings = LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: currentSettings.primaryComponent.languageCode, localization: Localization(version: difference.version, entries: mergedEntries), customPluralizationCode: currentSettings.primaryComponent.customPluralizationCode), secondaryComponent: currentSettings.secondaryComponent)
|
currentSettings = LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: currentSettings.primaryComponent.languageCode, localizedName: currentSettings.primaryComponent.localizedName, localization: Localization(version: difference.version, entries: mergedEntries), customPluralizationCode: currentSettings.primaryComponent.customPluralizationCode), secondaryComponent: currentSettings.secondaryComponent)
|
||||||
} else if let currentSecondary = currentSettings.secondaryComponent {
|
} else if let currentSecondary = currentSettings.secondaryComponent {
|
||||||
currentSettings = LocalizationSettings(primaryComponent: currentSettings.primaryComponent, secondaryComponent: LocalizationComponent(languageCode: currentSecondary.languageCode, localization: Localization(version: difference.version, entries: mergedEntries), customPluralizationCode: currentSecondary.customPluralizationCode))
|
currentSettings = LocalizationSettings(primaryComponent: currentSettings.primaryComponent, secondaryComponent: LocalizationComponent(languageCode: currentSecondary.languageCode, localizedName: currentSecondary.localizedName, localization: Localization(version: difference.version, entries: mergedEntries), customPluralizationCode: currentSecondary.customPluralizationCode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,13 +284,13 @@ func tryApplyingLanguageDifference(transaction: Transaction, langCode: String, d
|
|||||||
}
|
}
|
||||||
mergedEntries.append(contentsOf: updatedEntries)
|
mergedEntries.append(contentsOf: updatedEntries)
|
||||||
|
|
||||||
let currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
|
let currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
|
||||||
|
|
||||||
var updatedSettings: LocalizationSettings
|
var updatedSettings: LocalizationSettings
|
||||||
if isPrimary {
|
if isPrimary {
|
||||||
updatedSettings = LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: currentSettings.primaryComponent.languageCode, localization: Localization(version: updatedVersion, entries: mergedEntries), customPluralizationCode: currentSettings.primaryComponent.customPluralizationCode), secondaryComponent: currentSettings.secondaryComponent)
|
updatedSettings = LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: currentSettings.primaryComponent.languageCode, localizedName: currentSettings.primaryComponent.localizedName, localization: Localization(version: updatedVersion, entries: mergedEntries), customPluralizationCode: currentSettings.primaryComponent.customPluralizationCode), secondaryComponent: currentSettings.secondaryComponent)
|
||||||
} else if let currentSecondary = currentSettings.secondaryComponent {
|
} else if let currentSecondary = currentSettings.secondaryComponent {
|
||||||
updatedSettings = LocalizationSettings(primaryComponent: currentSettings.primaryComponent, secondaryComponent: LocalizationComponent(languageCode: currentSecondary.languageCode, localization: Localization(version: updatedVersion, entries: mergedEntries), customPluralizationCode: currentSecondary.customPluralizationCode))
|
updatedSettings = LocalizationSettings(primaryComponent: currentSettings.primaryComponent, secondaryComponent: LocalizationComponent(languageCode: currentSecondary.languageCode, localizedName: currentSecondary.localizedName, localization: Localization(version: updatedVersion, entries: mergedEntries), customPluralizationCode: currentSecondary.customPluralizationCode))
|
||||||
} else {
|
} else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -146,6 +146,7 @@ private enum PreferencesKeyValues: Int32 {
|
|||||||
case remoteStorageConfiguration = 10
|
case remoteStorageConfiguration = 10
|
||||||
case voipConfiguration = 11
|
case voipConfiguration = 11
|
||||||
case appChangelogState = 12
|
case appChangelogState = 12
|
||||||
|
case localizationListState = 13
|
||||||
}
|
}
|
||||||
|
|
||||||
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
||||||
@ -226,6 +227,12 @@ public struct PreferencesKeys {
|
|||||||
key.setInt32(0, value: PreferencesKeyValues.appChangelogState.rawValue)
|
key.setInt32(0, value: PreferencesKeyValues.appChangelogState.rawValue)
|
||||||
return key
|
return key
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public static let localizationListState: ValueBoxKey = {
|
||||||
|
let key = ValueBoxKey(length: 4)
|
||||||
|
key.setInt32(0, value: PreferencesKeyValues.localizationListState.rawValue)
|
||||||
|
return key
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum SharedDataKeyValues: Int32 {
|
private enum SharedDataKeyValues: Int32 {
|
||||||
|
|||||||
@ -202,7 +202,7 @@ public class BoxedMessage: NSObject {
|
|||||||
|
|
||||||
public class Serialization: NSObject, MTSerialization {
|
public class Serialization: NSObject, MTSerialization {
|
||||||
public func currentLayer() -> UInt {
|
public func currentLayer() -> UInt {
|
||||||
return 88
|
return 90
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parseMessage(_ data: Data!) -> Any! {
|
public func parseMessage(_ data: Data!) -> Any! {
|
||||||
|
|||||||
@ -209,7 +209,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe:
|
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp:
|
||||||
break
|
break
|
||||||
case let .messageActionChannelMigrateFrom(_, chatId):
|
case let .messageActionChannelMigrateFrom(_, chatId):
|
||||||
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId))
|
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId))
|
||||||
|
|||||||
@ -282,6 +282,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||||||
return nil
|
return nil
|
||||||
case let .messageActionSecureValuesSent(types):
|
case let .messageActionSecureValuesSent(types):
|
||||||
return TelegramMediaAction(action: .botSentSecureValues(types: types.map(SentSecureValueType.init)))
|
return TelegramMediaAction(action: .botSentSecureValues(types: types.map(SentSecureValueType.init)))
|
||||||
|
case .messageActionContactSignUp:
|
||||||
|
return TelegramMediaAction(action: .peerJoined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -281,8 +281,6 @@ extension Api.Update {
|
|||||||
case let .chatParticipantsForbidden(_, chatId, _):
|
case let .chatParticipantsForbidden(_, chatId, _):
|
||||||
return [PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)]
|
return [PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)]
|
||||||
}
|
}
|
||||||
case let .updateContactRegistered(userId, _):
|
|
||||||
return [PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)]
|
|
||||||
case let .updateDeleteChannelMessages(channelId, _, _, _):
|
case let .updateDeleteChannelMessages(channelId, _, _, _):
|
||||||
return [PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)]
|
return [PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)]
|
||||||
case let .updateNewChannelMessage(message, _, _):
|
case let .updateNewChannelMessage(message, _, _):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user