Merge branch 'master' of github.com:peter-iakovlev/TelegramCoreDev

This commit is contained in:
Ilya Laktyushin 2018-11-11 18:05:28 +04:00
commit ccd60ac08b
23 changed files with 369 additions and 173 deletions

View File

@ -366,6 +366,8 @@
D05A32E51E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */; };
D05A32E71E6F0B5C002760B4 /* 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 */; };
D0613FCB1E60440600202CDB /* InvitationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FC91E60440600202CDB /* InvitationLinks.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>"; };
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>"; };
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>"; };
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>"; };
@ -1680,6 +1683,7 @@
D08CAA7F1ED80ED20000FDA8 /* SuggestedLocalizationEntry.swift */,
D08CAA831ED8164B0000FDA8 /* Localization.swift */,
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */,
D05D8B362192F8AF0064586F /* LocalizationListState.swift */,
);
name = Localization;
sourceTree = "<group>";
@ -2179,6 +2183,7 @@
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */,
D00C7CEB1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
D09BB6B61DB0428000A905C0 /* PendingMessageUploadedContent.swift in Sources */,
D05D8B372192F8AF0064586F /* LocalizationListState.swift in Sources */,
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */,
D0B843B71DA7FF30005F29E1 /* NBMetadataCoreMapper.m in Sources */,
D0AB0B921D65E9FA002C78E7 /* ManagedServiceViews.swift in Sources */,
@ -2716,6 +2721,7 @@
D07047BB1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
D0380DBB204EF306000414AB /* MessageMediaPreuploadManager.swift in Sources */,
D050F2621E4A5AE700988324 /* GlobalNotificationSettings.swift in Sources */,
D05D8B382192F8AF0064586F /* LocalizationListState.swift in Sources */,
D0DFD5E01FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
D0E8174A2010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */,

View File

@ -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
if let peer = peer as? TelegramChannel, let addressName = peer.addressName, !addressName.isEmpty {
if let peer = peer as? TelegramChannel {
switch peer.info {
case .group:
if let addressName = peer.addressName, !addressName.isEmpty {
return [.publicGroups]
} else {
return [.regularChatsAndPrivateGroups]
}
case .broadcast:
return [.channels]
}

View File

@ -89,6 +89,7 @@ private var declaredEncodables: Void = {
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
declareEncodable(LocalizationListState.self, f: { LocalizationListState(decoder: $0) })
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
declareEncodable(NetworkSettings.self, f: { NetworkSettings(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> {
Logger.shared.log("AccountManager", "logoutFromAccount \(id)")
return accountManager.transaction { transaction -> Void in
let currentId = transaction.getCurrentId()
if let currentId = currentId {
transaction.updateRecord(currentId, { current in
transaction.updateRecord(id, { current in
if let current = current {
var found = false
for attribute in current.attributes {
@ -262,8 +261,9 @@ public func logoutFromAccount(id: AccountRecordId, accountManager: AccountManage
return nil
}
})
let id = transaction.createRecord([])
transaction.setCurrentId(id)
if transaction.getCurrentId() == id {
let updatedId = transaction.createRecord([])
transaction.setCurrentId(updatedId)
}
}
}
@ -285,14 +285,15 @@ public func managedCleanupAccounts(networkArguments: NetworkInitializationArgume
var disposeList: [(AccountRecordId, MetaDisposable)] = []
var beginList: [(AccountRecordId, MetaDisposable)] = []
let _ = loggedOutAccounts.modify { disposables in
let validIds = Set(view.records.filter {
for attribute in $0.attributes {
var validIds = Set<AccountRecordId>()
outer: for record in view.records {
for attribute in record.attributes {
if attribute is LoggedOutAccountAttribute {
return true
validIds.insert(record.id)
continue outer
}
}
}
return false
}.map { $0.id })
var disposables = disposables
@ -320,7 +321,7 @@ public func managedCleanupAccounts(networkArguments: NetworkInitializationArgume
disposable.dispose()
}
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())
}

View File

@ -101,13 +101,6 @@ private func locallyGeneratedMessageTimestampsFromUpdateGroups(_ groups: [Update
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:
break
}
@ -306,13 +299,6 @@ private func locallyGeneratedMessageTimestampsFromDifference(_ difference: Api.u
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:
break
}
@ -920,25 +906,6 @@ private func finalStateWithUpdatesAndServerTime(account: Account, state: Account
} else {
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):
updatedState.readInbox(MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: maxId))
case let .updateReadChannelOutbox(channelId, maxId):

View File

@ -110,6 +110,11 @@ public final class AccountStateManager {
return self.appliedIncomingReadMessagesPipe.signal()
}
private let significantStateUpdateCompletedPipe = ValuePipe<Void>()
var significantStateUpdateCompleted: Signal<Void, NoError> {
return self.significantStateUpdateCompletedPipe.signal()
}
private var updatedWebpageContexts: [MediaId: UpdatedWebpageSubscriberContext] = [:]
private let delayNotificatonsUntil = Atomic<Int32?>(value: nil)
@ -424,6 +429,7 @@ public final class AccountStateManager {
strongSelf.insertProcessEvents(events)
}
strongSelf.currentIsUpdatingValue = false
strongSelf.significantStateUpdateCompletedPipe.putNext(Void())
}
} else {
if !events.isEmpty {

View File

@ -89,7 +89,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
dict[414687501] = { return Api.DcOption.parse_dcOption($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[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($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[-1489818765] = { return Api.Update.parse_updateUserName($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[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($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[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($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[462375633] = { return Api.PhoneCall.parse_phoneCallWaiting($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[-1353671392] = { return Api.PeerNotifySettings.parse_peerNotifySettings($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[1326562017] = { return Api.UserProfilePhoto.parse_userProfilePhotoEmpty($0) }
dict[-715532088] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }

View File

@ -2362,13 +2362,13 @@ extension Api {
}
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) {
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 {
buffer.appendInt32(106019213)
buffer.appendInt32(-288727837)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(name, buffer: buffer, boxed: false)
@ -2378,14 +2378,15 @@ extension Api {
serializeString(pluralCode, buffer: buffer, boxed: false)
serializeInt32(stringsCount, buffer: buffer, boxed: false)
serializeInt32(translatedCount, buffer: buffer, boxed: false)
serializeString(translationsUrl, buffer: buffer, boxed: false)
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount):
return ("langPackLanguage", [("flags", flags), ("name", name), ("nativeName", nativeName), ("langCode", langCode), ("baseLangCode", baseLangCode), ("pluralCode", pluralCode), ("stringsCount", stringsCount), ("translatedCount", 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), ("translationsUrl", translationsUrl)])
}
}
@ -2406,6 +2407,8 @@ extension Api {
_7 = reader.readInt32()
var _8: Int32?
_8 = reader.readInt32()
var _9: String?
_9 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -2414,8 +2417,9 @@ extension Api {
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.LangPackLanguage.langPackLanguage(flags: _1!, name: _2!, nativeName: _3!, langCode: _4!, baseLangCode: _5, pluralCode: _6!, stringsCount: _7!, translatedCount: _8!)
let _c9 = _9 != nil
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 {
return nil
@ -3337,7 +3341,6 @@ extension Api {
case updateUserStatus(userId: Int32, status: Api.UserStatus)
case updateUserName(userId: Int32, firstName: String, lastName: String, username: String)
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 updateNewEncryptedMessage(message: Api.EncryptedMessage, qts: Int32)
case updateEncryptedChatTyping(chatId: Int32)
@ -3473,13 +3476,6 @@ extension Api {
photo.serialize(buffer, true)
previous.serialize(buffer, true)
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):
if boxed {
buffer.appendInt32(-1657903163)
@ -3988,8 +3984,6 @@ extension Api {
return ("updateUserName", [("userId", userId), ("firstName", firstName), ("lastName", lastName), ("username", username)])
case .updateUserPhoto(let userId, let date, let photo, let 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):
return ("updateContactLink", [("userId", userId), ("myLink", myLink), ("foreignLink", foreignLink)])
case .updateNewEncryptedMessage(let message, let qts):
@ -4271,20 +4265,6 @@ extension Api {
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? {
var _1: Int32?
_1 = reader.readInt32()
@ -15158,6 +15138,7 @@ extension Api {
case messageActionBotAllowed(domain: String)
case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted)
case messageActionSecureValuesSent(types: [Api.SecureValueType])
case messageActionContactSignUp(flags: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -15323,6 +15304,12 @@ extension Api {
item.serialize(buffer, true)
}
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)])
case .messageActionSecureValuesSent(let types):
return ("messageActionSecureValuesSent", [("types", types)])
case .messageActionContactSignUp(let flags):
return ("messageActionContactSignUp", [("flags", flags)])
}
}
@ -15637,6 +15626,17 @@ extension Api {
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 {
@ -16258,13 +16258,13 @@ extension Api {
}
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) {
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 {
buffer.appendInt32(-242812612)
buffer.appendInt32(-1282352120)
}
serializeInt32(flags, 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 << 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 << 3) != 0 {serializeString(author!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(publishedDate!, buffer: buffer, boxed: false)}
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .pageRelatedArticle(let flags, let url, let webpageId, let title, let description, let photoId):
return ("pageRelatedArticle", [("flags", flags), ("url", url), ("webpageId", webpageId), ("title", title), ("description", description), ("photoId", 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), ("author", author), ("publishedDate", publishedDate)])
}
}
@ -16296,14 +16298,20 @@ extension Api {
if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) }
var _6: Int64?
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 _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.PageRelatedArticle.pageRelatedArticle(flags: _1!, url: _2!, webpageId: _3!, title: _4, description: _5, photoId: _6)
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
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 {
return nil

View File

@ -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()
buffer.appendInt32(-558870880)
serializeString(email, buffer: buffer, boxed: false)
buffer.appendInt32(-1881204448)
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)
var result: Api.Bool?
if let signature = reader.readInt32() {

View File

@ -15,8 +15,8 @@ public enum ConfirmTwoStepRecoveryEmailError {
case generic
}
public func confirmTwoStepRecoveryEmail(network: Network, email: String, code: String) -> Signal<Never, ConfirmTwoStepRecoveryEmailError> {
return network.request(Api.functions.account.confirmPasswordEmail(email: email, code: code), automaticFloodWait: false)
public func confirmTwoStepRecoveryEmail(network: Network, code: String) -> Signal<Never, ConfirmTwoStepRecoveryEmailError> {
return network.request(Api.functions.account.confirmPasswordEmail(code: code), automaticFloodWait: false)
|> mapError { error -> ConfirmTwoStepRecoveryEmailError in
if error.errorDescription == "EMAIL_INVALID" {
return .invalidEmail
@ -31,3 +31,19 @@ public func confirmTwoStepRecoveryEmail(network: Network, email: String, code: S
}
|> 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
}

View File

@ -35,9 +35,11 @@ private final class ContactSyncManagerImpl {
private var nextId: Int32 = 0
private var operations: [ContactSyncOperation] = []
private var lastContactPresencesRequestTimestamp: Double?
private var reimportAttempts: [TelegramDeviceContactImportIdentifier: Double] = [:]
private let importableContactsDisposable = MetaDisposable()
private let significantStateUpdateCompletedDisposable = MetaDisposable()
init(queue: Queue, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager) {
self.queue = queue
@ -61,6 +63,36 @@ private final class ContactSyncManagerImpl {
strongSelf.addOperation(.updatePresences)
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)]) {

View File

@ -950,7 +950,7 @@ extension InstantPageTableRow {
extension InstantPageRelatedArticle {
convenience init(apiRelatedArticle: Api.PageRelatedArticle) {
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?
if let photoId = photoId {
posterPhotoId = MediaId(namespace: Namespaces.Media.CloudImage, id: photoId)

View File

@ -5,20 +5,21 @@ import Foundation
import Postbox
#endif
public final class LimitsConfiguration: PreferencesEntry {
public let maxGroupMemberCount: Int32
public let maxSupergroupMemberCount: Int32
public let maxMessageForwardBatchSize: Int32
public let maxSavedGifCount: Int32
public let maxRecentStickerCount: Int32
public let maxMessageEditingInterval: Int32
public let maxMediaCaptionLength: Int32
public struct LimitsConfiguration: Equatable, PreferencesEntry {
public var maxGroupMemberCount: Int32
public var maxSupergroupMemberCount: Int32
public var maxMessageForwardBatchSize: Int32
public var maxSavedGifCount: Int32
public var maxRecentStickerCount: Int32
public var maxMessageEditingInterval: Int32
public var maxMediaCaptionLength: Int32
public var canRemoveIncomingMessagesInPrivateChats: Bool
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.maxSupergroupMemberCount = maxSupergroupMemberCount
self.maxMessageForwardBatchSize = maxMessageForwardBatchSize
@ -26,6 +27,7 @@ public final class LimitsConfiguration: PreferencesEntry {
self.maxRecentStickerCount = maxRecentStickerCount
self.maxMessageEditingInterval = maxMessageEditingInterval
self.maxMediaCaptionLength = maxMediaCaptionLength
self.canRemoveIncomingMessagesInPrivateChats = canRemoveIncomingMessagesInPrivateChats
}
public init(decoder: PostboxDecoder) {
@ -36,6 +38,7 @@ public final class LimitsConfiguration: PreferencesEntry {
self.maxRecentStickerCount = decoder.decodeInt32ForKey("maxRecentStickerCount", orElse: 20)
self.maxMessageEditingInterval = decoder.decodeInt32ForKey("maxMessageEditingInterval", orElse: 2 * 24 * 60 * 60)
self.maxMediaCaptionLength = decoder.decodeInt32ForKey("maxMediaCaptionLength", orElse: 1000)
self.canRemoveIncomingMessagesInPrivateChats = decoder.decodeInt32ForKey("canRemoveIncomingMessagesInPrivateChats", orElse: 0) != 0
}
public func encode(_ encoder: PostboxEncoder) {
@ -46,34 +49,14 @@ public final class LimitsConfiguration: PreferencesEntry {
encoder.encodeInt32(self.maxRecentStickerCount, forKey: "maxRecentStickerCount")
encoder.encodeInt32(self.maxMessageEditingInterval, forKey: "maxMessageEditingInterval")
encoder.encodeInt32(self.maxMediaCaptionLength, forKey: "maxMediaCaptionLength")
encoder.encodeInt32(self.canRemoveIncomingMessagesInPrivateChats ? 1 : 0, forKey: "canRemoveIncomingMessagesInPrivateChats")
}
public func isEqual(to: PreferencesEntry) -> Bool {
guard let to = to as? LimitsConfiguration else {
return false
}
if self.maxGroupMemberCount != to.maxGroupMemberCount {
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
return self == to
}
}

View File

@ -5,7 +5,7 @@ import Foundation
import Postbox
#endif
public final class LocalizationInfo: PostboxCoding {
public struct LocalizationInfo: PostboxCoding, Equatable {
public let languageCode: String
public let baseLanguageCode: String?
public let customPluralizationCode: String?
@ -14,8 +14,9 @@ public final class LocalizationInfo: PostboxCoding {
public let isOfficial: Bool
public let totalStringCount: 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.baseLanguageCode = baseLanguageCode
self.customPluralizationCode = customPluralizationCode
@ -24,6 +25,7 @@ public final class LocalizationInfo: PostboxCoding {
self.isOfficial = isOfficial
self.totalStringCount = totalStringCount
self.translatedStringCount = translatedStringCount
self.platformUrl = platformUrl
}
public init(decoder: PostboxDecoder) {
@ -35,6 +37,7 @@ public final class LocalizationInfo: PostboxCoding {
self.isOfficial = decoder.decodeInt32ForKey("of", orElse: 0) != 0
self.totalStringCount = decoder.decodeInt32ForKey("tsc", orElse: 0)
self.translatedStringCount = decoder.decodeInt32ForKey("lsc", orElse: 0)
self.platformUrl = decoder.decodeStringForKey("platformUrl", orElse: "")
}
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.totalStringCount, forKey: "tsc")
encoder.encodeInt32(self.translatedStringCount, forKey: "lsc")
encoder.encodeString(self.platformUrl, forKey: "platformUrl")
}
}
extension LocalizationInfo {
convenience init(apiLanguage: Api.LangPackLanguage) {
init(apiLanguage: Api.LangPackLanguage) {
switch apiLanguage {
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)
}
}
}

View 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
}
}

View File

@ -7,23 +7,27 @@ import Foundation
public final class LocalizationComponent: Equatable, PostboxCoding {
public let languageCode: String
public let localizedName: String
public let localization: Localization
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.localizedName = localizedName
self.localization = localization
self.customPluralizationCode = customPluralizationCode
}
public init(decoder: PostboxDecoder) {
self.languageCode = decoder.decodeStringForKey("lc", orElse: "")
self.localizedName = decoder.decodeStringForKey("localizedName", orElse: "")
self.localization = decoder.decodeObjectForKey("loc", decoder: { Localization(decoder: $0) }) as! Localization
self.customPluralizationCode = decoder.decodeOptionalStringForKey("cpl")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.languageCode, forKey: "lc")
encoder.encodeString(self.localizedName, forKey: "localizedName")
encoder.encodeObject(self.localization, forKey: "loc")
if let customPluralizationCode = self.customPluralizationCode {
encoder.encodeString(customPluralizationCode, forKey: "cpl")
@ -36,6 +40,9 @@ public final class LocalizationComponent: Equatable, PostboxCoding {
if lhs.languageCode != rhs.languageCode {
return false
}
if lhs.localizedName != rhs.localizedName {
return false
}
if lhs.localization != rhs.localization {
return false
}
@ -57,7 +64,7 @@ public final class LocalizationSettings: PreferencesEntry, Equatable {
public init(decoder: PostboxDecoder) {
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
} else {
self.primaryComponent = decoder.decodeObjectForKey("primaryComponent", decoder: { LocalizationComponent(decoder: $0) }) as! LocalizationComponent

View File

@ -139,11 +139,23 @@ public func downloadAndApplyLocalization(postbox: Postbox, network: Network, lan
}
var secondaryComponent: LocalizationComponent?
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
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

View File

@ -60,7 +60,7 @@ func managedConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<V
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)
var invalidateLocalization = false

View File

@ -174,7 +174,7 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
return postbox.transaction { transaction -> Signal<Void, SynchronizeLocalizationUpdatesError> in
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 {
let current: (isPrimary: Bool, entries: [LocalizationEntry])
@ -205,9 +205,9 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
}
mergedEntries.append(contentsOf: difference.entries)
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 {
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)
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
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 {
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 {
assertionFailure()
return false

View File

@ -146,6 +146,7 @@ private enum PreferencesKeyValues: Int32 {
case remoteStorageConfiguration = 10
case voipConfiguration = 11
case appChangelogState = 12
case localizationListState = 13
}
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
@ -226,6 +227,12 @@ public struct PreferencesKeys {
key.setInt32(0, value: PreferencesKeyValues.appChangelogState.rawValue)
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 {

View File

@ -202,7 +202,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 88
return 90
}
public func parseMessage(_ data: Data!) -> Any! {

View File

@ -209,7 +209,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
}
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
case let .messageActionChannelMigrateFrom(_, chatId):
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId))

View File

@ -282,6 +282,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return nil
case let .messageActionSecureValuesSent(types):
return TelegramMediaAction(action: .botSentSecureValues(types: types.map(SentSecureValueType.init)))
case .messageActionContactSignUp:
return TelegramMediaAction(action: .peerJoined)
}
}

View File

@ -281,8 +281,6 @@ extension Api.Update {
case let .chatParticipantsForbidden(_, 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, _, _, _):
return [PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)]
case let .updateNewChannelMessage(message, _, _):