API updates

[skip ci]
This commit is contained in:
Peter 2019-06-14 01:21:42 +01:00
parent 819583121e
commit 7ffb9e3034
32 changed files with 2955 additions and 2787 deletions

View File

@ -4363,6 +4363,8 @@ Any member of this group will be able to see messages in the channel.";
"AddContact.ContactWillBeSharedNow" = "When you tap **Done**, your phone number will become visible to %@."; "AddContact.ContactWillBeSharedNow" = "When you tap **Done**, your phone number will become visible to %@.";
"AddContact.ContactWillBeSharedAfterMutual" = "Phone number will be visible once %1$@ adds you as a contact. Your phone number will become visible to %1$@."; "AddContact.ContactWillBeSharedAfterMutual" = "Phone number will be visible once %1$@ adds you as a contact. Your phone number will become visible to %1$@.";
"AddContact.SharedContactException" = "Share My Phone Number";
"AddContact.SharedContactExceptionInfo" = "You can make your phone visible to %@.";
"AddContact.StatusSuccess" = "%@ is now in your contacts list."; "AddContact.StatusSuccess" = "%@ is now in your contacts list.";
"Conversation.ShareMyPhoneNumber.StatusSuccess" = "%@ can now see your phone number."; "Conversation.ShareMyPhoneNumber.StatusSuccess" = "%@ can now see your phone number.";

View File

@ -1291,10 +1291,10 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.updatePeerChatInclusion(peerId: peer.peerId, groupId: PeerGroupId(rawValue: folderId), changedGroup: true) updatedState.updatePeerChatInclusion(peerId: peer.peerId, groupId: PeerGroupId(rawValue: folderId), changedGroup: true)
} }
} }
case let .updateContactLocated(contacts): case let .updatePeerLocated(contacts):
var peersNearby: [PeerNearby] = [] var peersNearby: [PeerNearby] = []
for case let .contactLocated(userId, expires, distance) in contacts { for case let .peerLocated(peer, expires, distance) in contacts {
peersNearby.append(PeerNearby(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), expires: expires, distance: distance)) peersNearby.append(PeerNearby(id: peer.peerId, expires: expires, distance: distance))
} }
updatedState.updatePeersNearby(peersNearby) updatedState.updatePeersNearby(peersNearby)
default: default:

View File

@ -202,7 +202,7 @@ private func wrappedHistoryViewAdditionalData(chatLocation: ChatLocation, additi
private final class PeerCachedDataContext { private final class PeerCachedDataContext {
var viewIds = Set<Int32>() var viewIds = Set<Int32>()
var timestamp: Double? var timestamp: Double?
var referenceData: CachedPeerData? var hasCachedData: Bool = false
let disposable = MetaDisposable() let disposable = MetaDisposable()
deinit { deinit {
@ -780,22 +780,22 @@ public final class AccountViewTracker {
} }
} }
private func updateCachedPeerData(peerId: PeerId, viewId: Int32, referenceData: CachedPeerData?) { private func updateCachedPeerData(peerId: PeerId, viewId: Int32, hasCachedData: Bool) {
self.queue.async { self.queue.async {
let context: PeerCachedDataContext let context: PeerCachedDataContext
var dataUpdated = false var dataUpdated = false
if let existingContext = self.cachedDataContexts[peerId] { if let existingContext = self.cachedDataContexts[peerId] {
context = existingContext context = existingContext
context.referenceData = referenceData context.hasCachedData = hasCachedData
if context.timestamp == nil || abs(CFAbsoluteTimeGetCurrent() - context.timestamp!) > 60.0 * 5 { if context.timestamp == nil || abs(CFAbsoluteTimeGetCurrent() - context.timestamp!) > 60.0 * 5 {
context.timestamp = CFAbsoluteTimeGetCurrent() context.timestamp = CFAbsoluteTimeGetCurrent()
dataUpdated = true dataUpdated = true
} }
} else { } else {
context = PeerCachedDataContext() context = PeerCachedDataContext()
context.referenceData = referenceData context.hasCachedData = hasCachedData
self.cachedDataContexts[peerId] = context self.cachedDataContexts[peerId] = context
if context.referenceData == nil || context.timestamp == nil || abs(CFAbsoluteTimeGetCurrent() - context.timestamp!) > 60.0 * 5 { if !context.hasCachedData || context.timestamp == nil || abs(CFAbsoluteTimeGetCurrent() - context.timestamp!) > 60.0 * 5 {
context.timestamp = CFAbsoluteTimeGetCurrent() context.timestamp = CFAbsoluteTimeGetCurrent()
dataUpdated = true dataUpdated = true
} }
@ -816,7 +816,7 @@ public final class AccountViewTracker {
context.viewIds.remove(id) context.viewIds.remove(id)
if context.viewIds.isEmpty { if context.viewIds.isEmpty {
context.disposable.set(nil) context.disposable.set(nil)
context.referenceData = nil context.hasCachedData = false
} }
} }
} }
@ -968,7 +968,7 @@ public final class AccountViewTracker {
} }
}, next: { [weak self] next, viewId in }, next: { [weak self] next, viewId in
if let strongSelf = self { if let strongSelf = self {
strongSelf.updateCachedPeerData(peerId: peerId, viewId: viewId, referenceData: next.cachedData) strongSelf.updateCachedPeerData(peerId: peerId, viewId: viewId, hasCachedData: next.cachedData != nil)
} }
}, disposed: { [weak self] viewId in }, disposed: { [weak self] viewId in
if let strongSelf = self { if let strongSelf = self {

View File

@ -10,7 +10,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) } dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) } dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[461151667] = { return Api.ChatFull.parse_chatFull($0) } dict[461151667] = { return Api.ChatFull.parse_chatFull($0) }
dict[-1736252138] = { return Api.ChatFull.parse_channelFull($0) } dict[277964371] = { return Api.ChatFull.parse_channelFull($0) }
dict[1465219162] = { return Api.PollResults.parse_pollResults($0) } dict[1465219162] = { return Api.PollResults.parse_pollResults($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) } dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) }
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) } dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
@ -172,7 +172,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[-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) }
dict[-1264392051] = { return Api.Update.parse_updateEncryption($0) } dict[-1264392051] = { return Api.Update.parse_updateEncryption($0) }
@ -234,7 +233,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[856380452] = { return Api.Update.parse_updateReadChannelInbox($0) } dict[856380452] = { return Api.Update.parse_updateReadChannelInbox($0) }
dict[-1667805217] = { return Api.Update.parse_updateReadHistoryInbox($0) } dict[-1667805217] = { return Api.Update.parse_updateReadHistoryInbox($0) }
dict[1786671974] = { return Api.Update.parse_updatePeerSettings($0) } dict[1786671974] = { return Api.Update.parse_updatePeerSettings($0) }
dict[1602468195] = { return Api.Update.parse_updateContactLocated($0) } dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) } dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
@ -247,7 +246,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-55902537] = { return Api.InputDialogPeer.parse_inputDialogPeer($0) } dict[-55902537] = { return Api.InputDialogPeer.parse_inputDialogPeer($0) }
dict[1684014375] = { return Api.InputDialogPeer.parse_inputDialogPeerFolder($0) } dict[1684014375] = { return Api.InputDialogPeer.parse_inputDialogPeerFolder($0) }
dict[-994444869] = { return Api.Error.parse_error($0) } dict[-994444869] = { return Api.Error.parse_error($0) }
dict[-1150339286] = { return Api.ContactLocated.parse_contactLocated($0) }
dict[-1560655744] = { return Api.KeyboardButton.parse_keyboardButton($0) } dict[-1560655744] = { return Api.KeyboardButton.parse_keyboardButton($0) }
dict[629866245] = { return Api.KeyboardButton.parse_keyboardButtonUrl($0) } dict[629866245] = { return Api.KeyboardButton.parse_keyboardButtonUrl($0) }
dict[1748655686] = { return Api.KeyboardButton.parse_keyboardButtonCallback($0) } dict[1748655686] = { return Api.KeyboardButton.parse_keyboardButtonCallback($0) }
@ -384,6 +382,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1895328189] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionStopPoll($0) } dict[-1895328189] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionStopPoll($0) }
dict[1129042607] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangePhoto($0) } dict[1129042607] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangePhoto($0) }
dict[-1569748965] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeLinkedChat($0) } dict[-1569748965] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeLinkedChat($0) }
dict[241923758] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeLocation($0) }
dict[-526508104] = { return Api.help.ProxyData.parse_proxyDataEmpty($0) } dict[-526508104] = { return Api.help.ProxyData.parse_proxyDataEmpty($0) }
dict[737668643] = { return Api.help.ProxyData.parse_proxyDataPromo($0) } dict[737668643] = { return Api.help.ProxyData.parse_proxyDataPromo($0) }
dict[-543777747] = { return Api.auth.ExportedAuthorization.parse_exportedAuthorization($0) } dict[-543777747] = { return Api.auth.ExportedAuthorization.parse_exportedAuthorization($0) }
@ -456,6 +455,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[871426631] = { return Api.SecureCredentialsEncrypted.parse_secureCredentialsEncrypted($0) } dict[871426631] = { return Api.SecureCredentialsEncrypted.parse_secureCredentialsEncrypted($0) }
dict[157948117] = { return Api.upload.File.parse_file($0) } dict[157948117] = { return Api.upload.File.parse_file($0) }
dict[-242427324] = { return Api.upload.File.parse_fileCdnRedirect($0) } dict[-242427324] = { return Api.upload.File.parse_fileCdnRedirect($0) }
dict[-1078612597] = { return Api.ChannelLocation.parse_channelLocationEmpty($0) }
dict[547062491] = { return Api.ChannelLocation.parse_channelLocation($0) }
dict[182649427] = { return Api.MessageRange.parse_messageRange($0) } dict[182649427] = { return Api.MessageRange.parse_messageRange($0) }
dict[946083368] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultSuccess($0) } dict[946083368] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultSuccess($0) }
dict[904138920] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultArchive($0) } dict[904138920] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultArchive($0) }
@ -702,9 +703,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1674235686] = { return Api.account.AutoDownloadSettings.parse_autoDownloadSettings($0) } dict[1674235686] = { return Api.account.AutoDownloadSettings.parse_autoDownloadSettings($0) }
dict[-445792507] = { return Api.DialogPeer.parse_dialogPeer($0) } dict[-445792507] = { return Api.DialogPeer.parse_dialogPeer($0) }
dict[1363483106] = { return Api.DialogPeer.parse_dialogPeerFolder($0) } dict[1363483106] = { return Api.DialogPeer.parse_dialogPeerFolder($0) }
dict[1599050311] = { return Api.ContactLink.parse_contactLinkUnknown($0) }
dict[-17968211] = { return Api.ContactLink.parse_contactLinkNone($0) }
dict[-721239344] = { return Api.ContactLink.parse_contactLinkContact($0) }
dict[-104284986] = { return Api.WebDocument.parse_webDocumentNoProxy($0) } dict[-104284986] = { return Api.WebDocument.parse_webDocumentNoProxy($0) }
dict[475467473] = { return Api.WebDocument.parse_webDocument($0) } dict[475467473] = { return Api.WebDocument.parse_webDocument($0) }
dict[-1290580579] = { return Api.contacts.Found.parse_found($0) } dict[-1290580579] = { return Api.contacts.Found.parse_found($0) }
@ -757,6 +755,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-931638658] = { return Api.EncryptedChat.parse_encryptedChatRequested($0) } dict[-931638658] = { return Api.EncryptedChat.parse_encryptedChatRequested($0) }
dict[-94974410] = { return Api.EncryptedChat.parse_encryptedChat($0) } dict[-94974410] = { return Api.EncryptedChat.parse_encryptedChat($0) }
dict[332848423] = { return Api.EncryptedChat.parse_encryptedChatDiscarded($0) } dict[332848423] = { return Api.EncryptedChat.parse_encryptedChatDiscarded($0) }
dict[-901375139] = { return Api.PeerLocated.parse_peerLocated($0) }
dict[922273905] = { return Api.Document.parse_documentEmpty($0) } dict[922273905] = { return Api.Document.parse_documentEmpty($0) }
dict[-1683841855] = { return Api.Document.parse_document($0) } dict[-1683841855] = { return Api.Document.parse_document($0) }
dict[-1707344487] = { return Api.messages.HighScores.parse_highScores($0) } dict[-1707344487] = { return Api.messages.HighScores.parse_highScores($0) }
@ -929,8 +928,6 @@ struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.Error: case let _1 as Api.Error:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.ContactLocated:
_1.serialize(buffer, boxed)
case let _1 as Api.KeyboardButton: case let _1 as Api.KeyboardButton:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.ContactStatus: case let _1 as Api.ContactStatus:
@ -1095,6 +1092,8 @@ struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.upload.File: case let _1 as Api.upload.File:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.ChannelLocation:
_1.serialize(buffer, boxed)
case let _1 as Api.MessageRange: case let _1 as Api.MessageRange:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.messages.StickerSetInstallResult: case let _1 as Api.messages.StickerSetInstallResult:
@ -1285,8 +1284,6 @@ struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.DialogPeer: case let _1 as Api.DialogPeer:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.ContactLink:
_1.serialize(buffer, boxed)
case let _1 as Api.WebDocument: case let _1 as Api.WebDocument:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.contacts.Found: case let _1 as Api.contacts.Found:
@ -1325,6 +1322,8 @@ struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.EncryptedChat: case let _1 as Api.EncryptedChat:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.PeerLocated:
_1.serialize(buffer, boxed)
case let _1 as Api.Document: case let _1 as Api.Document:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.messages.HighScores: case let _1 as Api.messages.HighScores:

View File

@ -51,7 +51,7 @@ extension Api {
} }
enum ChatFull: TypeConstructorDescription { enum ChatFull: TypeConstructorDescription {
case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?) case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?)
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, pts: Int32) case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, location: Api.ChannelLocation?, pts: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -74,9 +74,9 @@ extension Api {
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
break break
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let pts): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let pts):
if boxed { if boxed {
buffer.appendInt32(-1736252138) buffer.appendInt32(277964371)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
@ -103,7 +103,8 @@ extension Api {
if Int(flags) & Int(1 << 8) != 0 {stickerset!.serialize(buffer, true)} if Int(flags) & Int(1 << 8) != 0 {stickerset!.serialize(buffer, true)}
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(availableMinId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 9) != 0 {serializeInt32(availableMinId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {serializeInt32(linkedChatId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 14) != 0 {serializeInt32(linkedChatId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 15) != 0 {location!.serialize(buffer, true)}
serializeInt32(pts, buffer: buffer, boxed: false) serializeInt32(pts, buffer: buffer, boxed: false)
break break
} }
@ -113,8 +114,8 @@ extension Api {
switch self { switch self {
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId):
return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId)]) return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId)])
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let pts): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let pts):
return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("pts", pts)]) return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("location", location), ("pts", pts)])
} }
} }
@ -220,9 +221,13 @@ extension Api {
var _21: Int32? var _21: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_21 = reader.readInt32() } if Int(_1!) & Int(1 << 11) != 0 {_21 = reader.readInt32() }
var _22: Int32? var _22: Int32?
if Int(_1!) & Int(1 << 13) != 0 {_22 = reader.readInt32() } if Int(_1!) & Int(1 << 14) != 0 {_22 = reader.readInt32() }
var _23: Int32? var _23: Api.ChannelLocation?
_23 = reader.readInt32() if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() {
_23 = Api.parse(reader, signature: signature) as? Api.ChannelLocation
} }
var _24: Int32?
_24 = 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
@ -244,10 +249,11 @@ extension Api {
let _c19 = (Int(_1!) & Int(1 << 8) == 0) || _19 != nil let _c19 = (Int(_1!) & Int(1 << 8) == 0) || _19 != nil
let _c20 = (Int(_1!) & Int(1 << 9) == 0) || _20 != nil let _c20 = (Int(_1!) & Int(1 << 9) == 0) || _20 != nil
let _c21 = (Int(_1!) & Int(1 << 11) == 0) || _21 != nil let _c21 = (Int(_1!) & Int(1 << 11) == 0) || _21 != nil
let _c22 = (Int(_1!) & Int(1 << 13) == 0) || _22 != nil let _c22 = (Int(_1!) & Int(1 << 14) == 0) || _22 != nil
let _c23 = _23 != nil let _c23 = (Int(_1!) & Int(1 << 15) == 0) || _23 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 { let _c24 = _24 != nil
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, pts: _23!) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 {
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, location: _23, pts: _24!)
} }
else { else {
return nil return nil
@ -3943,7 +3949,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 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)
case updateEncryption(chat: Api.EncryptedChat, date: Int32) case updateEncryption(chat: Api.EncryptedChat, date: Int32)
@ -4005,7 +4010,7 @@ extension Api {
case updateReadChannelInbox(flags: Int32, folderId: Int32?, channelId: Int32, maxId: Int32, stillUnreadCount: Int32, pts: Int32) case updateReadChannelInbox(flags: Int32, folderId: Int32?, channelId: Int32, maxId: Int32, stillUnreadCount: Int32, pts: Int32)
case updateReadHistoryInbox(flags: Int32, folderId: Int32?, peer: Api.Peer, maxId: Int32, stillUnreadCount: Int32, pts: Int32, ptsCount: Int32) case updateReadHistoryInbox(flags: Int32, folderId: Int32?, peer: Api.Peer, maxId: Int32, stillUnreadCount: Int32, pts: Int32, ptsCount: Int32)
case updatePeerSettings(peer: Api.Peer, settings: Api.PeerSettings) case updatePeerSettings(peer: Api.Peer, settings: Api.PeerSettings)
case updateContactLocated(contacts: [Api.ContactLocated]) case updatePeerLocated(peers: [Api.PeerLocated])
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -4082,14 +4087,6 @@ extension Api {
photo.serialize(buffer, true) photo.serialize(buffer, true)
previous.serialize(buffer, true) previous.serialize(buffer, true)
break break
case .updateContactLink(let userId, let myLink, let foreignLink):
if boxed {
buffer.appendInt32(-1657903163)
}
serializeInt32(userId, buffer: buffer, boxed: false)
myLink.serialize(buffer, true)
foreignLink.serialize(buffer, true)
break
case .updateNewEncryptedMessage(let message, let qts): case .updateNewEncryptedMessage(let message, let qts):
if boxed { if boxed {
buffer.appendInt32(314359194) buffer.appendInt32(314359194)
@ -4605,13 +4602,13 @@ extension Api {
peer.serialize(buffer, true) peer.serialize(buffer, true)
settings.serialize(buffer, true) settings.serialize(buffer, true)
break break
case .updateContactLocated(let contacts): case .updatePeerLocated(let peers):
if boxed { if boxed {
buffer.appendInt32(1602468195) buffer.appendInt32(-1263546448)
} }
buffer.appendInt32(481674261) buffer.appendInt32(481674261)
buffer.appendInt32(Int32(contacts.count)) buffer.appendInt32(Int32(peers.count))
for item in contacts { for item in peers {
item.serialize(buffer, true) item.serialize(buffer, true)
} }
break break
@ -4638,8 +4635,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 .updateContactLink(let userId, let myLink, let foreignLink):
return ("updateContactLink", [("userId", userId), ("myLink", myLink), ("foreignLink", foreignLink)])
case .updateNewEncryptedMessage(let message, let qts): case .updateNewEncryptedMessage(let message, let qts):
return ("updateNewEncryptedMessage", [("message", message), ("qts", qts)]) return ("updateNewEncryptedMessage", [("message", message), ("qts", qts)])
case .updateEncryptedChatTyping(let chatId): case .updateEncryptedChatTyping(let chatId):
@ -4762,8 +4757,8 @@ extension Api {
return ("updateReadHistoryInbox", [("flags", flags), ("folderId", folderId), ("peer", peer), ("maxId", maxId), ("stillUnreadCount", stillUnreadCount), ("pts", pts), ("ptsCount", ptsCount)]) return ("updateReadHistoryInbox", [("flags", flags), ("folderId", folderId), ("peer", peer), ("maxId", maxId), ("stillUnreadCount", stillUnreadCount), ("pts", pts), ("ptsCount", ptsCount)])
case .updatePeerSettings(let peer, let settings): case .updatePeerSettings(let peer, let settings):
return ("updatePeerSettings", [("peer", peer), ("settings", settings)]) return ("updatePeerSettings", [("peer", peer), ("settings", settings)])
case .updateContactLocated(let contacts): case .updatePeerLocated(let peers):
return ("updateContactLocated", [("contacts", contacts)]) return ("updatePeerLocated", [("peers", peers)])
} }
} }
@ -4927,27 +4922,6 @@ extension Api {
return nil return nil
} }
} }
static func parse_updateContactLink(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.ContactLink?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.ContactLink
}
var _3: Api.ContactLink?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.ContactLink
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateContactLink(userId: _1!, myLink: _2!, foreignLink: _3!)
}
else {
return nil
}
}
static func parse_updateNewEncryptedMessage(_ reader: BufferReader) -> Update? { static func parse_updateNewEncryptedMessage(_ reader: BufferReader) -> Update? {
var _1: Api.EncryptedMessage? var _1: Api.EncryptedMessage?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -5986,14 +5960,14 @@ extension Api {
return nil return nil
} }
} }
static func parse_updateContactLocated(_ reader: BufferReader) -> Update? { static func parse_updatePeerLocated(_ reader: BufferReader) -> Update? {
var _1: [Api.ContactLocated]? var _1: [Api.PeerLocated]?
if let _ = reader.readInt32() { if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ContactLocated.self) _1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PeerLocated.self)
} }
let _c1 = _1 != nil let _c1 = _1 != nil
if _c1 { if _c1 {
return Api.Update.updateContactLocated(contacts: _1!) return Api.Update.updatePeerLocated(peers: _1!)
} }
else { else {
return nil return nil
@ -6338,48 +6312,6 @@ extension Api {
} }
} }
}
enum ContactLocated: TypeConstructorDescription {
case contactLocated(userId: Int32, expires: Int32, distance: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .contactLocated(let userId, let expires, let distance):
if boxed {
buffer.appendInt32(-1150339286)
}
serializeInt32(userId, buffer: buffer, boxed: false)
serializeInt32(expires, buffer: buffer, boxed: false)
serializeInt32(distance, buffer: buffer, boxed: false)
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .contactLocated(let userId, let expires, let distance):
return ("contactLocated", [("userId", userId), ("expires", expires), ("distance", distance)])
}
}
static func parse_contactLocated(_ reader: BufferReader) -> ContactLocated? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.ContactLocated.contactLocated(userId: _1!, expires: _2!, distance: _3!)
}
else {
return nil
}
}
} }
enum KeyboardButton: TypeConstructorDescription { enum KeyboardButton: TypeConstructorDescription {
case keyboardButton(text: String) case keyboardButton(text: String)
@ -9267,6 +9199,7 @@ extension Api {
case channelAdminLogEventActionStopPoll(message: Api.Message) case channelAdminLogEventActionStopPoll(message: Api.Message)
case channelAdminLogEventActionChangePhoto(prevPhoto: Api.Photo, newPhoto: Api.Photo) case channelAdminLogEventActionChangePhoto(prevPhoto: Api.Photo, newPhoto: Api.Photo)
case channelAdminLogEventActionChangeLinkedChat(prevValue: Int32, newValue: Int32) case channelAdminLogEventActionChangeLinkedChat(prevValue: Int32, newValue: Int32)
case channelAdminLogEventActionChangeLocation(prevValue: Api.ChannelLocation, newValue: Api.ChannelLocation)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -9394,6 +9327,13 @@ extension Api {
serializeInt32(prevValue, buffer: buffer, boxed: false) serializeInt32(prevValue, buffer: buffer, boxed: false)
serializeInt32(newValue, buffer: buffer, boxed: false) serializeInt32(newValue, buffer: buffer, boxed: false)
break break
case .channelAdminLogEventActionChangeLocation(let prevValue, let newValue):
if boxed {
buffer.appendInt32(241923758)
}
prevValue.serialize(buffer, true)
newValue.serialize(buffer, true)
break
} }
} }
@ -9437,6 +9377,8 @@ extension Api {
return ("channelAdminLogEventActionChangePhoto", [("prevPhoto", prevPhoto), ("newPhoto", newPhoto)]) return ("channelAdminLogEventActionChangePhoto", [("prevPhoto", prevPhoto), ("newPhoto", newPhoto)])
case .channelAdminLogEventActionChangeLinkedChat(let prevValue, let newValue): case .channelAdminLogEventActionChangeLinkedChat(let prevValue, let newValue):
return ("channelAdminLogEventActionChangeLinkedChat", [("prevValue", prevValue), ("newValue", newValue)]) return ("channelAdminLogEventActionChangeLinkedChat", [("prevValue", prevValue), ("newValue", newValue)])
case .channelAdminLogEventActionChangeLocation(let prevValue, let newValue):
return ("channelAdminLogEventActionChangeLocation", [("prevValue", prevValue), ("newValue", newValue)])
} }
} }
@ -9701,6 +9643,24 @@ extension Api {
return nil return nil
} }
} }
static func parse_channelAdminLogEventActionChangeLocation(_ reader: BufferReader) -> ChannelAdminLogEventAction? {
var _1: Api.ChannelLocation?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.ChannelLocation
}
var _2: Api.ChannelLocation?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.ChannelLocation
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.ChannelAdminLogEventAction.channelAdminLogEventActionChangeLocation(prevValue: _1!, newValue: _2!)
}
else {
return nil
}
}
} }
enum SecurePlainData: TypeConstructorDescription { enum SecurePlainData: TypeConstructorDescription {
@ -11404,6 +11364,58 @@ extension Api {
} }
} }
}
enum ChannelLocation: TypeConstructorDescription {
case channelLocationEmpty
case channelLocation(geoPoint: Api.GeoPoint, address: String)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .channelLocationEmpty:
if boxed {
buffer.appendInt32(-1078612597)
}
break
case .channelLocation(let geoPoint, let address):
if boxed {
buffer.appendInt32(547062491)
}
geoPoint.serialize(buffer, true)
serializeString(address, buffer: buffer, boxed: false)
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .channelLocationEmpty:
return ("channelLocationEmpty", [])
case .channelLocation(let geoPoint, let address):
return ("channelLocation", [("geoPoint", geoPoint), ("address", address)])
}
}
static func parse_channelLocationEmpty(_ reader: BufferReader) -> ChannelLocation? {
return Api.ChannelLocation.channelLocationEmpty
}
static func parse_channelLocation(_ reader: BufferReader) -> ChannelLocation? {
var _1: Api.GeoPoint?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.GeoPoint
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.ChannelLocation.channelLocation(geoPoint: _1!, address: _2!)
}
else {
return nil
}
}
} }
enum MessageRange: TypeConstructorDescription { enum MessageRange: TypeConstructorDescription {
case messageRange(minId: Int32, maxId: Int32) case messageRange(minId: Int32, maxId: Int32)
@ -17788,56 +17800,6 @@ extension Api {
} }
} }
}
enum ContactLink: TypeConstructorDescription {
case contactLinkUnknown
case contactLinkNone
case contactLinkContact
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .contactLinkUnknown:
if boxed {
buffer.appendInt32(1599050311)
}
break
case .contactLinkNone:
if boxed {
buffer.appendInt32(-17968211)
}
break
case .contactLinkContact:
if boxed {
buffer.appendInt32(-721239344)
}
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .contactLinkUnknown:
return ("contactLinkUnknown", [])
case .contactLinkNone:
return ("contactLinkNone", [])
case .contactLinkContact:
return ("contactLinkContact", [])
}
}
static func parse_contactLinkUnknown(_ reader: BufferReader) -> ContactLink? {
return Api.ContactLink.contactLinkUnknown
}
static func parse_contactLinkNone(_ reader: BufferReader) -> ContactLink? {
return Api.ContactLink.contactLinkNone
}
static func parse_contactLinkContact(_ reader: BufferReader) -> ContactLink? {
return Api.ContactLink.contactLinkContact
}
} }
enum WebDocument: TypeConstructorDescription { enum WebDocument: TypeConstructorDescription {
case webDocumentNoProxy(url: String, size: Int32, mimeType: String, attributes: [Api.DocumentAttribute]) case webDocumentNoProxy(url: String, size: Int32, mimeType: String, attributes: [Api.DocumentAttribute])
@ -19086,6 +19048,50 @@ extension Api {
} }
} }
}
enum PeerLocated: TypeConstructorDescription {
case peerLocated(peer: Api.Peer, expires: Int32, distance: Int32)
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .peerLocated(let peer, let expires, let distance):
if boxed {
buffer.appendInt32(-901375139)
}
peer.serialize(buffer, true)
serializeInt32(expires, buffer: buffer, boxed: false)
serializeInt32(distance, buffer: buffer, boxed: false)
break
}
}
func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .peerLocated(let peer, let expires, let distance):
return ("peerLocated", [("peer", peer), ("expires", expires), ("distance", distance)])
}
}
static func parse_peerLocated(_ reader: BufferReader) -> PeerLocated? {
var _1: Api.Peer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.PeerLocated.peerLocated(peer: _1!, expires: _2!, distance: _3!)
}
else {
return nil
}
}
} }
enum Document: TypeConstructorDescription { enum Document: TypeConstructorDescription {
case documentEmpty(id: Int64) case documentEmpty(id: Int64)

View File

@ -2674,24 +2674,6 @@ extension Api {
}) })
} }
static func searchGlobal(q: String, offsetRate: Int32, offsetPeer: Api.InputPeer, offsetId: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Messages>) {
let buffer = Buffer()
buffer.appendInt32(259638801)
serializeString(q, buffer: buffer, boxed: false)
serializeInt32(offsetRate, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.searchGlobal", parameters: [("q", q), ("offsetRate", offsetRate), ("offsetPeer", offsetPeer), ("offsetId", offsetId), ("limit", limit)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
static func getSearchCounters(peer: Api.InputPeer, filters: [Api.MessagesFilter]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.messages.SearchCounter]>) { static func getSearchCounters(peer: Api.InputPeer, filters: [Api.MessagesFilter]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.messages.SearchCounter]>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(1932455680) buffer.appendInt32(1932455680)
@ -2744,6 +2726,26 @@ extension Api {
}) })
} }
static func searchGlobal(flags: Int32, folderId: Int32?, q: String, offsetRate: Int32, offsetPeer: Api.InputPeer, offsetId: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Messages>) {
let buffer = Buffer()
buffer.appendInt32(-1083038300)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
serializeString(q, buffer: buffer, boxed: false)
serializeInt32(offsetRate, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.searchGlobal", parameters: [("flags", flags), ("folderId", folderId), ("q", q), ("offsetRate", offsetRate), ("offsetPeer", offsetPeer), ("offsetId", offsetId), ("limit", limit)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
static func hidePeerSettingsBar(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func hidePeerSettingsBar(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(1336717624) buffer.appendInt32(1336717624)
@ -3289,6 +3291,22 @@ extension Api {
return result return result
}) })
} }
static func editLocation(channel: Api.InputChannel, geoPoint: Api.InputGeoPoint, address: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1491484525)
channel.serialize(buffer, true)
geoPoint.serialize(buffer, true)
serializeString(address, buffer: buffer, boxed: false)
return (FunctionDescription(name: "channels.editLocation", parameters: [("channel", channel), ("geoPoint", geoPoint), ("address", address)]), 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
})
}
} }
struct payments { struct payments {
static func getPaymentForm(msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentForm>) { static func getPaymentForm(msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentForm>) {
@ -3956,14 +3974,15 @@ extension Api {
}) })
} }
static func addContact(id: Api.InputUser, firstName: String, lastName: String, phone: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { static func addContact(flags: Int32, id: Api.InputUser, firstName: String, lastName: String, phone: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-2035792455) buffer.appendInt32(-386636848)
serializeInt32(flags, buffer: buffer, boxed: false)
id.serialize(buffer, true) id.serialize(buffer, true)
serializeString(firstName, buffer: buffer, boxed: false) serializeString(firstName, buffer: buffer, boxed: false)
serializeString(lastName, buffer: buffer, boxed: false) serializeString(lastName, buffer: buffer, boxed: false)
serializeString(phone, buffer: buffer, boxed: false) serializeString(phone, buffer: buffer, boxed: false)
return (FunctionDescription(name: "contacts.addContact", parameters: [("id", id), ("firstName", firstName), ("lastName", lastName), ("phone", phone)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in return (FunctionDescription(name: "contacts.addContact", parameters: [("flags", flags), ("id", id), ("firstName", firstName), ("lastName", lastName), ("phone", phone)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -4005,12 +4024,11 @@ extension Api {
}) })
} }
static func getLocated(geoPoint: Api.InputGeoPoint, radius: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { static func getLocated(geoPoint: Api.InputGeoPoint) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-261936023) buffer.appendInt32(171270230)
geoPoint.serialize(buffer, true) geoPoint.serialize(buffer, true)
serializeInt32(radius, buffer: buffer, boxed: false) return (FunctionDescription(name: "contacts.getLocated", parameters: [("geoPoint", geoPoint)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
return (FunctionDescription(name: "contacts.getLocated", parameters: [("geoPoint", geoPoint), ("radius", radius)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {

View File

@ -57,7 +57,9 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: id), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: id), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
case let .chatForbidden(id, title): case let .chatForbidden(id, title):
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: id), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: id), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
case let .channel(flags, id, accessHash, title, username, photo, date, version, restrictionReason, adminRights, bannedRights, defaultBannedRights, _/*feed*//*, feedId*/): case let .channel(flags, id, accessHash, title, username, photo, date, version, restrictionReason, adminRights, bannedRights, defaultBannedRights, _):
let isMin = (flags & (1 << 20)) != 0
let participationStatus: TelegramChannelParticipationStatus let participationStatus: TelegramChannelParticipationStatus
if (flags & Int32(1 << 1)) != 0 { if (flags & Int32(1 << 1)) != 0 {
participationStatus = .kicked participationStatus = .kicked

View File

@ -214,6 +214,8 @@ public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: Pe
} }
case let .channelAdminLogEventActionChangeLinkedChat(prevValue, newValue): case let .channelAdminLogEventActionChangeLinkedChat(prevValue, newValue):
action = .linkedPeerUpdated(previous: prevValue == 0 ? nil : peers[PeerId(namespace: Namespaces.Peer.CloudChannel, id: prevValue)], updated: newValue == 0 ? nil : peers[PeerId(namespace: Namespaces.Peer.CloudChannel, id: newValue)]) action = .linkedPeerUpdated(previous: prevValue == 0 ? nil : peers[PeerId(namespace: Namespaces.Peer.CloudChannel, id: prevValue)], updated: newValue == 0 ? nil : peers[PeerId(namespace: Namespaces.Peer.CloudChannel, id: newValue)])
case let .channelAdminLogEventActionChangeLocation(prevValue, newValue):
break
} }
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
if let action = action { if let action = action {

View File

@ -44,7 +44,7 @@ public enum AddContactError {
case generic case generic
} }
public func addContactInteractively(account: Account, peerId: PeerId, firstName: String, lastName: String, phoneNumber: String) -> Signal<Never, AddContactError> { public func addContactInteractively(account: Account, peerId: PeerId, firstName: String, lastName: String, phoneNumber: String, addToPrivacyExceptions: Bool) -> Signal<Never, AddContactError> {
return account.postbox.transaction { transaction -> (Api.InputUser, String)? in return account.postbox.transaction { transaction -> (Api.InputUser, String)? in
if let user = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(user) { if let user = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(user) {
return (inputUser, user.phone == nil ? phoneNumber : "") return (inputUser, user.phone == nil ? phoneNumber : "")
@ -57,7 +57,11 @@ public func addContactInteractively(account: Account, peerId: PeerId, firstName:
guard let (inputUser, phone) = inputUserAndPhone else { guard let (inputUser, phone) = inputUserAndPhone else {
return .fail(.generic) return .fail(.generic)
} }
return account.network.request(Api.functions.contacts.addContact(id: inputUser, firstName: firstName, lastName: lastName, phone: phone)) var flags: Int32 = 0
if addToPrivacyExceptions {
flags |= (1 << 0)
}
return account.network.request(Api.functions.contacts.addContact(flags: flags, id: inputUser, firstName: firstName, lastName: lastName, phone: phone))
|> mapError { _ -> AddContactError in |> mapError { _ -> AddContactError in
return .generic return .generic
} }

View File

@ -0,0 +1,6 @@
import Foundation
public enum TelegramPeerAccessHash: Hashable {
case personal(Int64)
case genericPublic(Int64)
}

View File

@ -16,6 +16,7 @@ public struct PeerStatusSettings: OptionSet {
public static let canShareContact = PeerStatusSettings(rawValue: 1 << 2) public static let canShareContact = PeerStatusSettings(rawValue: 1 << 2)
public static let canBlock = PeerStatusSettings(rawValue: 1 << 3) public static let canBlock = PeerStatusSettings(rawValue: 1 << 3)
public static let canAddContact = PeerStatusSettings(rawValue: 1 << 4) public static let canAddContact = PeerStatusSettings(rawValue: 1 << 4)
public static let addExceptionWhenAddingContact = PeerStatusSettings(rawValue: 1 << 5)
} }
extension PeerStatusSettings { extension PeerStatusSettings {
@ -35,6 +36,9 @@ extension PeerStatusSettings {
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
result.insert(.canShareContact) result.insert(.canShareContact)
} }
if (flags & (1 << 4)) != 0 {
result.insert(.addExceptionWhenAddingContact)
}
self = result self = result
} }
} }

View File

@ -16,7 +16,7 @@ public struct PeerNearby {
public func peersNearby(network: Network, accountStateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double), radius: Int32) -> Signal<[PeerNearby], NoError> { public func peersNearby(network: Network, accountStateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double), radius: Int32) -> Signal<[PeerNearby], NoError> {
let inputGeoPoint = Api.InputGeoPoint.inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude) let inputGeoPoint = Api.InputGeoPoint.inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude)
return network.request(Api.functions.contacts.getLocated(geoPoint: inputGeoPoint, radius: radius)) return network.request(Api.functions.contacts.getLocated(geoPoint: inputGeoPoint))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in |> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil) return .single(nil)
@ -27,9 +27,9 @@ public func peersNearby(network: Network, accountStateManager: AccountStateManag
switch updates { switch updates {
case let .updates(updates, _, _, _, _): case let .updates(updates, _, _, _, _):
for update in updates { for update in updates {
if case let .updateContactLocated(contacts) = update { if case let .updatePeerLocated(peers) = update {
for case let .contactLocated(userId, expires, distance) in contacts { for case let .peerLocated(peer, expires, distance) in peers {
peersNearby.append(PeerNearby(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), expires: expires, distance: distance)) peersNearby.append(PeerNearby(id: peer.peerId, expires: expires, distance: distance))
} }
} }
} }

View File

@ -13,6 +13,20 @@ public func removePeerChat(account: Account, peerId: PeerId, reportChatSpam: Boo
} }
} }
public func terminateSecretChat(transaction: Transaction, peerId: PeerId) {
if let state = transaction.getPeerChatState(peerId) as? SecretChatState, state.embeddedState != .terminated {
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate(reportSpam: false), state: state).withUpdatedEmbeddedState(.terminated)
if updatedState != state {
transaction.setPeerChatState(peerId, state: updatedState)
if let peer = transaction.getPeer(peerId) as? TelegramSecretChat {
updatePeers(transaction: transaction, peers: [peer.withUpdatedEmbeddedState(updatedState.embeddedState.peerState)], update: { _, updated in
return updated
})
}
}
}
}
public func removePeerChat(account: Account, transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, reportChatSpam: Bool, deleteGloballyIfPossible: Bool) { public func removePeerChat(account: Account, transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, reportChatSpam: Bool, deleteGloballyIfPossible: Bool) {
if let _ = transaction.getPeerChatInterfaceState(peerId) { if let _ = transaction.getPeerChatInterfaceState(peerId) {
transaction.updatePeerChatInterfaceState(peerId, update: { current in transaction.updatePeerChatInterfaceState(peerId, update: { current in
@ -24,8 +38,7 @@ public func removePeerChat(account: Account, transaction: Transaction, mediaBox:
}) })
} }
if peerId.namespace == Namespaces.Peer.SecretChat { if peerId.namespace == Namespaces.Peer.SecretChat {
if let state = transaction.getPeerChatState(peerId) as? SecretChatState { if let state = transaction.getPeerChatState(peerId) as? SecretChatState, state.embeddedState != .terminated {
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate(reportSpam: reportChatSpam), state: state).withUpdatedEmbeddedState(.terminated) let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: SecretChatOutgoingOperationContents.terminate(reportSpam: reportChatSpam), state: state).withUpdatedEmbeddedState(.terminated)
if updatedState != state { if updatedState != state {
transaction.setPeerChatState(peerId, state: updatedState) transaction.setPeerChatState(peerId, state: updatedState)

View File

@ -291,7 +291,7 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q
} }
} }
|> mapToSignal { (nextRate, lowerBound, inputPeer) in |> mapToSignal { (nextRate, lowerBound, inputPeer) in
account.network.request(Api.functions.messages.searchGlobal(q: query, offsetRate: nextRate, offsetPeer: inputPeer, offsetId: lowerBound?.id.id ?? 0, limit: limit), automaticFloodWait: false) account.network.request(Api.functions.messages.searchGlobal(flags: 0, folderId: nil, q: query, offsetRate: nextRate, offsetPeer: inputPeer, offsetId: lowerBound?.id.id ?? 0, limit: limit), automaticFloodWait: false)
|> map { result -> (Api.messages.Messages?, Api.messages.Messages?) in |> map { result -> (Api.messages.Messages?, Api.messages.Messages?) in
return (result, nil) return (result, nil)
} }

View File

@ -302,8 +302,9 @@ extension TelegramUser {
static func merge(_ lhs: TelegramUser?, rhs: Api.User) -> TelegramUser? { static func merge(_ lhs: TelegramUser?, rhs: Api.User) -> TelegramUser? {
switch rhs { switch rhs {
case let .user(flags, _, accessHash, _, _, username, _, photo, _, _, restrictionReason, botInlinePlaceholder, _): case let .user(flags, _, _, _, _, username, _, photo, _, _, restrictionReason, botInlinePlaceholder, _):
if let _ = accessHash { let isMin = (flags & (1 << 20)) != 0
if !isMin {
return TelegramUser(user: rhs) return TelegramUser(user: rhs)
} else { } else {
let telegramPhoto = photo.flatMap(parsedTelegramProfilePhoto) ?? [] let telegramPhoto = photo.flatMap(parsedTelegramProfilePhoto) ?? []

View File

@ -7,10 +7,23 @@ import Foundation
import SwiftSignalKit import SwiftSignalKit
#endif #endif
func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> { func fetchAndUpdateSupplementalCachedPeerData(peerId rawPeerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Signal<Void, NoError> in return postbox.transaction { transaction -> Signal<Void, NoError> in
if let peer = transaction.getPeer(peerId) { guard let rawPeer = transaction.getPeer(rawPeerId) else {
let cachedData = transaction.getPeerCachedData(peerId: peerId) return .complete()
}
let peer: Peer
if let secretChat = rawPeer as? TelegramSecretChat {
guard let user = transaction.getPeer(secretChat.regularPeerId) else {
return .complete()
}
peer = user
} else {
peer = rawPeer
}
let cachedData = transaction.getPeerCachedData(peerId: peer.id)
if let cachedData = cachedData as? CachedUserData { if let cachedData = cachedData as? CachedUserData {
if cachedData.peerStatusSettings != nil { if cachedData.peerStatusSettings != nil {
@ -30,10 +43,10 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network,
} }
} }
if peerId.namespace == Namespaces.Peer.SecretChat { if peer.id.namespace == Namespaces.Peer.SecretChat {
return postbox.transaction { transaction -> Void in return postbox.transaction { transaction -> Void in
var peerStatusSettings: PeerStatusSettings var peerStatusSettings: PeerStatusSettings
if let peer = transaction.getPeer(peerId), let associatedPeerId = peer.associatedPeerId, !transaction.isPeerContact(peerId: associatedPeerId) { if let peer = transaction.getPeer(peer.id), let associatedPeerId = peer.associatedPeerId, !transaction.isPeerContact(peerId: associatedPeerId) {
if let peer = peer as? TelegramSecretChat, case .creator = peer.role { if let peer = peer as? TelegramSecretChat, case .creator = peer.role {
peerStatusSettings = PeerStatusSettings() peerStatusSettings = PeerStatusSettings()
peerStatusSettings = [] peerStatusSettings = []
@ -46,7 +59,7 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network,
peerStatusSettings = [] peerStatusSettings = []
} }
transaction.updatePeerCachedData(peerIds: [peerId], update: { peerId, current in transaction.updatePeerCachedData(peerIds: [peer.id], update: { peerId, current in
if let current = current as? CachedSecretChatData { if let current = current as? CachedSecretChatData {
return current.withUpdatedPeerStatusSettings(peerStatusSettings) return current.withUpdatedPeerStatusSettings(peerStatusSettings)
} else { } else {
@ -61,8 +74,8 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network,
let peerStatusSettings = PeerStatusSettings(apiSettings: peerSettings) let peerStatusSettings = PeerStatusSettings(apiSettings: peerSettings)
return postbox.transaction { transaction -> Void in return postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in
switch peerId.namespace { switch peer.id.namespace {
case Namespaces.Peer.CloudUser: case Namespaces.Peer.CloudUser:
let previous: CachedUserData let previous: CachedUserData
if let current = current as? CachedUserData { if let current = current as? CachedUserData {
@ -97,22 +110,37 @@ func fetchAndUpdateSupplementalCachedPeerData(peerId: PeerId, network: Network,
} else { } else {
return .complete() return .complete()
} }
} else {
return .complete()
} }
} |> switchToLatest |> switchToLatest
} }
func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> { func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerId, network: Network, postbox: Postbox) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> (Api.InputUser?, Peer?) in return postbox.transaction { transaction -> (Api.InputUser?, Peer?, PeerId) in
if peerId == accountPeerId { guard let rawPeer = transaction.getPeer(rawPeerId) else {
return (.inputUserSelf, transaction.getPeer(peerId)) if rawPeerId == accountPeerId {
return (.inputUserSelf, transaction.getPeer(rawPeerId), rawPeerId)
} else { } else {
let peer = transaction.getPeer(peerId) return (nil, nil, rawPeerId)
return (peer.flatMap(apiInputUser), peer)
} }
} }
|> mapToSignal { inputUser, maybePeer -> Signal<Void, NoError> in
let peer: Peer
if let secretChat = rawPeer as? TelegramSecretChat {
guard let user = transaction.getPeer(secretChat.regularPeerId) else {
return (nil, nil, rawPeerId)
}
peer = user
} else {
peer = rawPeer
}
if rawPeerId == accountPeerId {
return (.inputUserSelf, transaction.getPeer(rawPeerId), rawPeerId)
} else {
return (apiInputUser(peer), peer, peer.id)
}
}
|> mapToSignal { inputUser, maybePeer, peerId -> Signal<Void, NoError> in
if let inputUser = inputUser { if let inputUser = inputUser {
return network.request(Api.functions.users.getFullUser(id: inputUser)) return network.request(Api.functions.users.getFullUser(id: inputUser))
|> retryRequest |> retryRequest
@ -250,7 +278,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId: PeerId, network
} }
switch fullChat { switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, pts): case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, pts):
var channelFlags = CachedChannelFlags() var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants) channelFlags.insert(.canDisplayParticipants)

View File

@ -451,6 +451,8 @@
D073CEA11DCBF3D3007511FD /* StickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0DE1DB539FC00C6B04F /* StickerPack.swift */; }; D073CEA11DCBF3D3007511FD /* StickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0DE1DB539FC00C6B04F /* StickerPack.swift */; };
D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03C53761DAFF20F004C17B3 /* MultipartUpload.swift */; }; D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03C53761DAFF20F004C17B3 /* MultipartUpload.swift */; };
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0E11DB5401A00C6B04F /* StickerManagement.swift */; }; D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0E11DB5401A00C6B04F /* StickerManagement.swift */; };
D0750C9022B2FD8300BE5F6E /* PeerAccessHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0750C8F22B2FD8300BE5F6E /* PeerAccessHash.swift */; };
D0750C9122B2FD8300BE5F6E /* PeerAccessHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0750C8F22B2FD8300BE5F6E /* PeerAccessHash.swift */; };
D0754D2A1EEE10FC00884F6E /* BotPaymentForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */; }; D0754D2A1EEE10FC00884F6E /* BotPaymentForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */; };
D0754D2B1EEE10FC00884F6E /* BotPaymentForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */; }; D0754D2B1EEE10FC00884F6E /* BotPaymentForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */; };
D076F8892296D8E9004F895A /* ManageChannelDiscussionGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D076F8882296D8E9004F895A /* ManageChannelDiscussionGroup.swift */; }; D076F8892296D8E9004F895A /* ManageChannelDiscussionGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D076F8882296D8E9004F895A /* ManageChannelDiscussionGroup.swift */; };
@ -1066,6 +1068,7 @@
D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsumePersonalMessageAction.swift; sourceTree = "<group>"; }; D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsumePersonalMessageAction.swift; sourceTree = "<group>"; };
D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardSourceInfoAttribute.swift; sourceTree = "<group>"; }; D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardSourceInfoAttribute.swift; sourceTree = "<group>"; };
D073CE5F1DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingMessageInfoAttribute.swift; sourceTree = "<group>"; }; D073CE5F1DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingMessageInfoAttribute.swift; sourceTree = "<group>"; };
D0750C8F22B2FD8300BE5F6E /* PeerAccessHash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerAccessHash.swift; sourceTree = "<group>"; };
D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BotPaymentForm.swift; sourceTree = "<group>"; }; D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BotPaymentForm.swift; sourceTree = "<group>"; };
D076F8882296D8E9004F895A /* ManageChannelDiscussionGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageChannelDiscussionGroup.swift; sourceTree = "<group>"; }; D076F8882296D8E9004F895A /* ManageChannelDiscussionGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageChannelDiscussionGroup.swift; sourceTree = "<group>"; };
D07827BA1E00451F00071108 /* SearchPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchPeers.swift; sourceTree = "<group>"; }; D07827BA1E00451F00071108 /* SearchPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchPeers.swift; sourceTree = "<group>"; };
@ -1445,6 +1448,7 @@
D03B0CDA1D62245F00955575 /* ApiUtils.swift */, D03B0CDA1D62245F00955575 /* ApiUtils.swift */,
D03B0CD81D62245B00955575 /* PeerUtils.swift */, D03B0CD81D62245B00955575 /* PeerUtils.swift */,
D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */, D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */,
D0750C8F22B2FD8300BE5F6E /* PeerAccessHash.swift */,
D03B0CD41D62245300955575 /* TelegramUser.swift */, D03B0CD41D62245300955575 /* TelegramUser.swift */,
D03B0CD51D62245300955575 /* TelegramGroup.swift */, D03B0CD51D62245300955575 /* TelegramGroup.swift */,
D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */, D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */,
@ -2398,6 +2402,7 @@
D0E412E7206ABC7500BEE4A2 /* EncryptedMediaResource.swift in Sources */, D0E412E7206ABC7500BEE4A2 /* EncryptedMediaResource.swift in Sources */,
D0AB262621C2F991008F6685 /* TelegramMediaPoll.swift in Sources */, D0AB262621C2F991008F6685 /* TelegramMediaPoll.swift in Sources */,
D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */, D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */,
D0750C9022B2FD8300BE5F6E /* PeerAccessHash.swift in Sources */,
D0FC195B2020D1CA00FEDBB2 /* PeerGroupMessageStateVersionAttribute.swift in Sources */, D0FC195B2020D1CA00FEDBB2 /* PeerGroupMessageStateVersionAttribute.swift in Sources */,
D0B1671D1F9EA2C300976B40 /* ChatHistoryPreloadManager.swift in Sources */, D0B1671D1F9EA2C300976B40 /* ChatHistoryPreloadManager.swift in Sources */,
D02B199021FB1D520094A764 /* RegisterNotificationToken.swift in Sources */, D02B199021FB1D520094A764 /* RegisterNotificationToken.swift in Sources */,
@ -2661,6 +2666,7 @@
D0C26D6A1FE02402004ABF18 /* ManagedSynchronizeGroupedPeersOperations.swift in Sources */, D0C26D6A1FE02402004ABF18 /* ManagedSynchronizeGroupedPeersOperations.swift in Sources */,
D01C7F051EFC1C49008305F1 /* DeviceContact.swift in Sources */, D01C7F051EFC1C49008305F1 /* DeviceContact.swift in Sources */,
D050F26A1E4A5B6D00988324 /* ManagedGlobalNotificationSettings.swift in Sources */, D050F26A1E4A5B6D00988324 /* ManagedGlobalNotificationSettings.swift in Sources */,
D0750C9122B2FD8300BE5F6E /* PeerAccessHash.swift in Sources */,
D050F26B1E4A5B6D00988324 /* ApplyMaxReadIndexInteractively.swift in Sources */, D050F26B1E4A5B6D00988324 /* ApplyMaxReadIndexInteractively.swift in Sources */,
D033FEB11E61EB0200644997 /* PeerContactSettings.swift in Sources */, D033FEB11E61EB0200644997 /* PeerContactSettings.swift in Sources */,
D0458C891E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */, D0458C891E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift in Sources */,

View File

@ -5834,7 +5834,9 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
} }
private func reportPeer() { private func reportPeer() {
if let peer = self.presentationInterfaceState.renderedPeer?.peer { guard let renderedPeer = self.presentationInterfaceState.renderedPeer, let peer = renderedPeer.chatMainPeer, let chatPeer = renderedPeer.peer else {
return
}
self.chatDisplayNode.dismissInput() self.chatDisplayNode.dismissInput()
if let peer = peer as? TelegramChannel, let username = peer.username, !username.isEmpty { if let peer = peer as? TelegramChannel, let username = peer.username, !username.isEmpty {
@ -5876,8 +5878,13 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
return return
} }
let _ = requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: true).start() let _ = requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: true).start()
if let _ = chatPeer as? TelegramSecretChat {
let _ = (strongSelf.context.account.postbox.transaction { transaction in
terminateSecretChat(transaction: transaction, peerId: chatPeer.id)
}).start()
}
if deleteChat { if deleteChat {
let _ = removePeerChat(account: strongSelf.context.account, peerId: peer.id, reportChatSpam: reportSpam).start() let _ = removePeerChat(account: strongSelf.context.account, peerId: chatPeer.id, reportChatSpam: reportSpam).start()
(strongSelf.navigationController as? NavigationController)?.filterController(strongSelf, animated: true) (strongSelf.navigationController as? NavigationController)?.filterController(strongSelf, animated: true)
} else if reportSpam { } else if reportSpam {
let _ = TelegramCore.reportPeer(account: strongSelf.context.account, peerId: peer.id, reason: .spam).start() let _ = TelegramCore.reportPeer(account: strongSelf.context.account, peerId: peer.id, reason: .spam).start()
@ -5919,7 +5926,6 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
self.present(actionSheet, in: .window(.root)) self.present(actionSheet, in: .window(.root))
} }
} }
}
private func shareAccountContact() { private func shareAccountContact() {
let _ = (self.context.account.postbox.loadedPeerWithId(self.context.account.peerId) let _ = (self.context.account.postbox.loadedPeerWithId(self.context.account.peerId)
@ -5950,8 +5956,8 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
} }
private func addPeerContact() { private func addPeerContact() {
if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramUser, let contactData = DeviceContactExtendedData(peer: peer) { if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramUser, let peerStatusSettings = self.presentationInterfaceState.contactStatus?.peerStatusSettings, let contactData = DeviceContactExtendedData(peer: peer) {
self.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: true, completion: { [weak self] peer, stableId, contactData in self.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: true, shareViaException: peerStatusSettings.contains(.addExceptionWhenAddingContact), completion: { [weak self] peer, stableId, contactData in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }

View File

@ -29,7 +29,7 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
} }
var displayActionsPanel = false var displayActionsPanel = false
if let contactStatus = chatPresentationInterfaceState.contactStatus, let peerStatusSettings = contactStatus.peerStatusSettings { if !chatPresentationInterfaceState.peerIsBlocked, let contactStatus = chatPresentationInterfaceState.contactStatus, let peerStatusSettings = contactStatus.peerStatusSettings {
if !peerStatusSettings.isEmpty { if !peerStatusSettings.isEmpty {
if contactStatus.canAddContact && peerStatusSettings.contains(.canAddContact) { if contactStatus.canAddContact && peerStatusSettings.contains(.canAddContact) {
displayActionsPanel = true displayActionsPanel = true

View File

@ -9,6 +9,7 @@ private enum ChatReportPeerTitleButton: Equatable {
case block case block
case addContact(String?) case addContact(String?)
case shareMyPhoneNumber case shareMyPhoneNumber
case reportSpam
func title(strings: PresentationStrings) -> String { func title(strings: PresentationStrings) -> String {
switch self { switch self {
@ -22,6 +23,8 @@ private enum ChatReportPeerTitleButton: Equatable {
} }
case .shareMyPhoneNumber: case .shareMyPhoneNumber:
return strings.Conversation_ShareMyPhoneNumber return strings.Conversation_ShareMyPhoneNumber
case .reportSpam:
return strings.Conversation_ReportSpam
} }
} }
} }
@ -46,6 +49,8 @@ private func peerButtons(_ state: ChatPresentationInterfaceState) -> [ChatReport
buttons.append(.shareMyPhoneNumber) buttons.append(.shareMyPhoneNumber)
} }
} }
} else if let _ = state.renderedPeer?.chatMainPeer {
buttons.append(.reportSpam)
} }
return buttons return buttons
} }
@ -141,7 +146,8 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode {
nextButtonOrigin += buttonWidth nextButtonOrigin += buttonWidth
} }
} else { } else {
let areaWidth = width - maxInset * 2.0 let additionalRightInset: CGFloat = 18.0
let areaWidth = width - maxInset * 2.0 - additionalRightInset
let maxButtonWidth = floor(areaWidth / CGFloat(self.buttons.count)) let maxButtonWidth = floor(areaWidth / CGFloat(self.buttons.count))
let buttonSizes = self.buttons.map { button -> CGFloat in let buttonSizes = self.buttons.map { button -> CGFloat in
return button.1.sizeThatFits(CGSize(width: maxButtonWidth, height: 100.0)).width return button.1.sizeThatFits(CGSize(width: maxButtonWidth, height: 100.0)).width
@ -171,7 +177,7 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode {
switch button { switch button {
case .shareMyPhoneNumber: case .shareMyPhoneNumber:
self.interfaceInteraction?.shareAccountContact() self.interfaceInteraction?.shareAccountContact()
case .block: case .block, .reportSpam:
self.interfaceInteraction?.reportPeer() self.interfaceInteraction?.reportPeer()
case .addContact: case .addContact:
self.interfaceInteraction?.presentPeerContact() self.interfaceInteraction?.presentPeerContact()

View File

@ -381,8 +381,8 @@ public class ContactsController: ViewController {
switch status { switch status {
case .allowed: case .allowed:
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: []) let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [])
strongSelf.present(deviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, completion: { peer, stableId, contactData in strongSelf.present(deviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }

View File

@ -192,17 +192,19 @@ public final class DeviceContactInstantMessagingProfileData: Equatable, Hashable
} }
} }
private let phonebookUsernamePrefix = "t.me/id"
public extension DeviceContactInstantMessagingProfileData { public extension DeviceContactInstantMessagingProfileData {
convenience init(appProfile: PeerId) { convenience init(appProfile: PeerId) {
self.init(label: "mobile", service: "Telegram", username: "@id\(appProfile.id)") self.init(label: "mobile", service: "Telegram", username: "\(phonebookUsernamePrefix)\(appProfile.id)")
} }
} }
func parseAppSpecificContactReference(_ value: String) -> PeerId? { func parseAppSpecificContactReference(_ value: String) -> PeerId? {
if !value.hasPrefix("@id") { if !value.hasPrefix(phonebookUsernamePrefix) {
return nil return nil
} }
let idString = String(value[value.index(value.startIndex, offsetBy: 3)...]) let idString = String(value[value.index(value.startIndex, offsetBy: phonebookUsernamePrefix.count)...])
if let id = Int32(idString) { if let id = Int32(idString) {
return PeerId(namespace: Namespaces.Peer.CloudUser, id: id) return PeerId(namespace: Namespaces.Peer.CloudUser, id: id)
} }

View File

@ -27,8 +27,9 @@ private final class DeviceContactInfoControllerArguments {
let openUrl: (String) -> Void let openUrl: (String) -> Void
let openAddress: (DeviceContactAddressData) -> Void let openAddress: (DeviceContactAddressData) -> Void
let displayCopyContextMenu: (DeviceContactInfoEntryTag, String) -> Void let displayCopyContextMenu: (DeviceContactInfoEntryTag, String) -> Void
let updateShareViaException: (Bool) -> Void
init(account: Account, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updatePhone: @escaping (Int64, String) -> Void, updatePhoneLabel: @escaping (Int64, String) -> Void, deletePhone: @escaping (Int64) -> Void, setPhoneIdWithRevealedOptions: @escaping (Int64?, Int64?) -> Void, addPhoneNumber: @escaping () -> Void, performAction: @escaping (DeviceContactInfoAction) -> Void, toggleSelection: @escaping (DeviceContactInfoDataId) -> Void, callPhone: @escaping (String) -> Void, openUrl: @escaping (String) -> Void, openAddress: @escaping (DeviceContactAddressData) -> Void, displayCopyContextMenu: @escaping (DeviceContactInfoEntryTag, String) -> Void) { init(account: Account, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updatePhone: @escaping (Int64, String) -> Void, updatePhoneLabel: @escaping (Int64, String) -> Void, deletePhone: @escaping (Int64) -> Void, setPhoneIdWithRevealedOptions: @escaping (Int64?, Int64?) -> Void, addPhoneNumber: @escaping () -> Void, performAction: @escaping (DeviceContactInfoAction) -> Void, toggleSelection: @escaping (DeviceContactInfoDataId) -> Void, callPhone: @escaping (String) -> Void, openUrl: @escaping (String) -> Void, openAddress: @escaping (DeviceContactAddressData) -> Void, displayCopyContextMenu: @escaping (DeviceContactInfoEntryTag, String) -> Void, updateShareViaException: @escaping (Bool) -> Void) {
self.account = account self.account = account
self.updateEditingName = updateEditingName self.updateEditingName = updateEditingName
self.updatePhone = updatePhone self.updatePhone = updatePhone
@ -42,6 +43,7 @@ private final class DeviceContactInfoControllerArguments {
self.openUrl = openUrl self.openUrl = openUrl
self.openAddress = openAddress self.openAddress = openAddress
self.displayCopyContextMenu = displayCopyContextMenu self.displayCopyContextMenu = displayCopyContextMenu
self.updateShareViaException = updateShareViaException
} }
} }
@ -49,6 +51,7 @@ private enum DeviceContactInfoSection: ItemListSectionId {
case info case info
case editing case editing
case data case data
case share
} }
private enum DeviceContactInfoEntryTag: Equatable, ItemListItemTag { private enum DeviceContactInfoEntryTag: Equatable, ItemListItemTag {
@ -82,6 +85,8 @@ private enum DeviceContactInfoConstantEntryId: Hashable {
case birthday case birthday
case addPhoneNumber case addPhoneNumber
case phoneNumberSharingInfo case phoneNumberSharingInfo
case phoneNumberShareViaException
case phoneNumberShareViaExceptionInfo
} }
private enum DeviceContactInfoEntryId: Hashable { private enum DeviceContactInfoEntryId: Hashable {
@ -107,6 +112,8 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
case phoneNumber(Int, Int, PresentationTheme, String, String, String, Bool?, Bool) case phoneNumber(Int, Int, PresentationTheme, String, String, String, Bool?, Bool)
case editingPhoneNumber(Int, PresentationTheme, PresentationStrings, Int64, String, String, String, Bool) case editingPhoneNumber(Int, PresentationTheme, PresentationStrings, Int64, String, String, String, Bool)
case phoneNumberSharingInfo(Int, PresentationTheme, String) case phoneNumberSharingInfo(Int, PresentationTheme, String)
case phoneNumberShareViaException(Int, PresentationTheme, String, Bool)
case phoneNumberShareViaExceptionInfo(Int, PresentationTheme, String)
case addPhoneNumber(Int, PresentationTheme, String) case addPhoneNumber(Int, PresentationTheme, String)
case email(Int, Int, PresentationTheme, String, String, String, Bool?) case email(Int, Int, PresentationTheme, String, String, String, Bool?)
case url(Int, Int, PresentationTheme, String, String, String, Bool?) case url(Int, Int, PresentationTheme, String, String, String, Bool?)
@ -123,6 +130,8 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
return DeviceContactInfoSection.editing.rawValue return DeviceContactInfoSection.editing.rawValue
case .invite, .sendMessage, .createContact, .addToExisting: case .invite, .sendMessage, .createContact, .addToExisting:
return DeviceContactInfoSection.info.rawValue return DeviceContactInfoSection.info.rawValue
case .phoneNumberShareViaException, .phoneNumberShareViaExceptionInfo:
return DeviceContactInfoSection.share.rawValue
default: default:
return DeviceContactInfoSection.data.rawValue return DeviceContactInfoSection.data.rawValue
} }
@ -146,6 +155,10 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
return .phoneNumber(catIndex) return .phoneNumber(catIndex)
case .phoneNumberSharingInfo: case .phoneNumberSharingInfo:
return .constant(.phoneNumberSharingInfo) return .constant(.phoneNumberSharingInfo)
case .phoneNumberShareViaException:
return .constant(.phoneNumberShareViaException)
case .phoneNumberShareViaExceptionInfo:
return .constant(.phoneNumberShareViaExceptionInfo)
case let .editingPhoneNumber(_, _, _, id, _, _, _, _): case let .editingPhoneNumber(_, _, _, id, _, _, _, _):
return .editingPhoneNumber(id) return .editingPhoneNumber(id)
case .addPhoneNumber: case .addPhoneNumber:
@ -236,6 +249,18 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .phoneNumberShareViaException(lhsIndex, lhsTheme, lhsText, lhsValue):
if case let .phoneNumberShareViaException(rhsIndex, rhsTheme, rhsText, rhsValue) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .phoneNumberShareViaExceptionInfo(lhsIndex, lhsTheme, lhsText):
if case let .phoneNumberShareViaExceptionInfo(rhsIndex, rhsTheme, rhsText) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .editingPhoneNumber(lhsIndex, lhsTheme, lhsStrings, lhsId, lhsTitle, lhsLabel, lhsValue, lhsSelected): case let .editingPhoneNumber(lhsIndex, lhsTheme, lhsStrings, lhsId, lhsTitle, lhsLabel, lhsValue, lhsSelected):
if case let .editingPhoneNumber(rhsIndex, rhsTheme, rhsStrings, rhsId, rhsTitle, rhsLabel, rhsValue, rhsSelected) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsId == rhsId, lhsTitle == rhsTitle, lhsLabel == rhsLabel, lhsValue == rhsValue, lhsSelected == rhsSelected { if case let .editingPhoneNumber(rhsIndex, rhsTheme, rhsStrings, rhsId, rhsTitle, rhsLabel, rhsValue, rhsSelected) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsId == rhsId, lhsTitle == rhsTitle, lhsLabel == rhsLabel, lhsValue == rhsValue, lhsSelected == rhsSelected {
return true return true
@ -305,6 +330,10 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
return index return index
case let .phoneNumberSharingInfo(index, _, _): case let .phoneNumberSharingInfo(index, _, _):
return index return index
case let .phoneNumberShareViaException(index, _, _, _):
return index
case let .phoneNumberShareViaExceptionInfo(index, _, _):
return index
case let .editingPhoneNumber(index, _, _, _, _, _, _, _): case let .editingPhoneNumber(index, _, _, _, _, _, _, _):
return index return index
case let .addPhoneNumber(index, _, _): case let .addPhoneNumber(index, _, _):
@ -361,13 +390,19 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
} else { } else {
arguments.callPhone(value) arguments.callPhone(value)
} }
} : nil, longTapAction: { } : nil, longTapAction: isInteractionEnabled ? {
if selected == nil { if selected == nil {
arguments.displayCopyContextMenu(.info(index), value) arguments.displayCopyContextMenu(.info(index), value)
} }
}, tag: DeviceContactInfoEntryTag.info(index)) } : nil, tag: DeviceContactInfoEntryTag.info(index))
case let .phoneNumberSharingInfo(_, theme, text): case let .phoneNumberSharingInfo(_, theme, text):
return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section) return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section)
case let .phoneNumberShareViaException(_, theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .plain, updated: { value in
arguments.updateShareViaException(value)
})
case let .phoneNumberShareViaExceptionInfo(_, theme, text):
return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section)
case let .editingPhoneNumber(_, theme, strings, id, title, label, value, hasActiveRevealControls): case let .editingPhoneNumber(_, theme, strings, id, title, label, value, hasActiveRevealControls):
return UserInfoEditingPhoneItem(theme: theme, strings: strings, id: id, label: title, value: value, editing: UserInfoEditingPhoneItemEditing(editable: true, hasActiveRevealControls: hasActiveRevealControls), sectionId: self.section, setPhoneIdWithRevealedOptions: { lhs, rhs in return UserInfoEditingPhoneItem(theme: theme, strings: strings, id: id, label: title, value: value, editing: UserInfoEditingPhoneItemEditing(editable: true, hasActiveRevealControls: hasActiveRevealControls), sectionId: self.section, setPhoneIdWithRevealedOptions: { lhs, rhs in
arguments.setPhoneIdWithRevealedOptions(lhs, rhs) arguments.setPhoneIdWithRevealedOptions(lhs, rhs)
@ -500,6 +535,7 @@ private struct EditingPhoneNumber: Equatable {
private struct DeviceContactInfoState: Equatable { private struct DeviceContactInfoState: Equatable {
var savingData: Bool = false var savingData: Bool = false
var addToPrivacyExceptions: Bool = true
var editingState: DeviceContactInfoEditingState? = nil var editingState: DeviceContactInfoEditingState? = nil
var excludedComponents = Set<DeviceContactInfoDataId>() var excludedComponents = Set<DeviceContactInfoDataId>()
var phoneNumbers: [EditingPhoneNumber] = [] var phoneNumbers: [EditingPhoneNumber] = []
@ -532,7 +568,7 @@ private func filteredContactData(contactData: DeviceContactExtendedData, exclude
return DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumbers: phoneNumbers), middleName: contactData.middleName, prefix: contactData.prefix, suffix: contactData.suffix, organization: includeJob ? contactData.organization : "", jobTitle: includeJob ? contactData.jobTitle : "", department: includeJob ? contactData.department : "", emailAddresses: emailAddresses, urls: urls, addresses: addresses, birthdayDate: includeBirthday ? contactData.birthdayDate : nil, socialProfiles: socialProfiles, instantMessagingProfiles: instantMessagingProfiles) return DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumbers: phoneNumbers), middleName: contactData.middleName, prefix: contactData.prefix, suffix: contactData.suffix, organization: includeJob ? contactData.organization : "", jobTitle: includeJob ? contactData.jobTitle : "", department: includeJob ? contactData.department : "", emailAddresses: emailAddresses, urls: urls, addresses: addresses, birthdayDate: includeBirthday ? contactData.birthdayDate : nil, socialProfiles: socialProfiles, instantMessagingProfiles: instantMessagingProfiles)
} }
private func deviceContactInfoEntries(account: Account, presentationData: PresentationData, peer: Peer?, isShare: Bool, contactData: DeviceContactExtendedData, isContact: Bool, state: DeviceContactInfoState, selecting: Bool, editingPhoneNumbers: Bool) -> [DeviceContactInfoEntry] { private func deviceContactInfoEntries(account: Account, presentationData: PresentationData, peer: Peer?, isShare: Bool, shareViaException: Bool, contactData: DeviceContactExtendedData, isContact: Bool, state: DeviceContactInfoState, selecting: Bool, editingPhoneNumbers: Bool) -> [DeviceContactInfoEntry] {
var entries: [DeviceContactInfoEntry] = [] var entries: [DeviceContactInfoEntry] = []
var editingName: ItemListAvatarAndNameInfoItemName? var editingName: ItemListAvatarAndNameInfoItemName?
@ -597,6 +633,10 @@ private func deviceContactInfoEntries(account: Account, presentationData: Presen
} else { } else {
entries.append(.phoneNumberSharingInfo(entries.count, presentationData.theme, presentationData.strings.AddContact_ContactWillBeSharedNow(peer.compactDisplayTitle).0)) entries.append(.phoneNumberSharingInfo(entries.count, presentationData.theme, presentationData.strings.AddContact_ContactWillBeSharedNow(peer.compactDisplayTitle).0))
} }
if shareViaException {
entries.append(.phoneNumberShareViaException(entries.count, presentationData.theme, presentationData.strings.AddContact_SharedContactException, state.addToPrivacyExceptions))
entries.append(.phoneNumberShareViaExceptionInfo(entries.count, presentationData.theme, presentationData.strings.AddContact_SharedContactExceptionInfo(peer.compactDisplayTitle).0))
}
} }
} else { } else {
if editingPhoneNumbers { if editingPhoneNumbers {
@ -691,7 +731,7 @@ private func deviceContactInfoEntries(account: Account, presentationData: Presen
public enum DeviceContactInfoSubject { public enum DeviceContactInfoSubject {
case vcard(Peer?, DeviceContactStableId?, DeviceContactExtendedData) case vcard(Peer?, DeviceContactStableId?, DeviceContactExtendedData)
case filter(peer: Peer?, contactId: DeviceContactStableId?, contactData: DeviceContactExtendedData, completion: (Peer?, DeviceContactExtendedData) -> Void) case filter(peer: Peer?, contactId: DeviceContactStableId?, contactData: DeviceContactExtendedData, completion: (Peer?, DeviceContactExtendedData) -> Void)
case create(peer: Peer?, contactData: DeviceContactExtendedData, isSharing: Bool, completion: (Peer?, DeviceContactStableId, DeviceContactExtendedData) -> Void) case create(peer: Peer?, contactData: DeviceContactExtendedData, isSharing: Bool, shareViaException: Bool, completion: (Peer?, DeviceContactStableId, DeviceContactExtendedData) -> Void)
var peer: Peer? { var peer: Peer? {
switch self { switch self {
@ -710,7 +750,7 @@ public enum DeviceContactInfoSubject {
return data return data
case let .filter(_, _, data, _): case let .filter(_, _, data, _):
return data return data
case let .create(_, data, _, _): case let .create(_, data, _, _, _):
return data return data
} }
} }
@ -746,7 +786,7 @@ private final class DeviceContactInfoController: ItemListController<DeviceContac
public func deviceContactInfoController(context: AccountContext, subject: DeviceContactInfoSubject, completed: (() -> Void)? = nil, cancelled: (() -> Void)? = nil) -> ViewController { public func deviceContactInfoController(context: AccountContext, subject: DeviceContactInfoSubject, completed: (() -> Void)? = nil, cancelled: (() -> Void)? = nil) -> ViewController {
var initialState = DeviceContactInfoState() var initialState = DeviceContactInfoState()
if case let .create(peer, contactData, _, _) = subject { if case let .create(peer, contactData, _, _, _) = subject {
var peerPhoneNumber: String? var peerPhoneNumber: String?
var firstName = contactData.basicData.firstName var firstName = contactData.basicData.firstName
var lastName = contactData.basicData.lastName var lastName = contactData.basicData.lastName
@ -917,7 +957,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} }
case .createContact: case .createContact:
presentControllerImpl?(deviceContactInfoController(context: context, subject: .create(peer: subject.peer, contactData: subject.contactData, isSharing: false, completion: { peer, stableId, contactData in presentControllerImpl?(deviceContactInfoController(context: context, subject: .create(peer: subject.peer, contactData: subject.contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
dismissImpl?(false) dismissImpl?(false)
if let peer = peer { if let peer = peer {
@ -950,18 +990,26 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
openAddressImpl?(address) openAddressImpl?(address)
}, displayCopyContextMenu: { tag, value in }, displayCopyContextMenu: { tag, value in
displayCopyContextMenuImpl?(tag, value) displayCopyContextMenuImpl?(tag, value)
}, updateShareViaException: { value in
updateState { state in
var state = state
state.addToPrivacyExceptions = value
return state
}
}) })
let contactData: Signal<(Peer?, DeviceContactStableId?, DeviceContactExtendedData), NoError> let contactData: Signal<(Peer?, DeviceContactStableId?, DeviceContactExtendedData), NoError>
var isShare = false var isShare = false
var shareViaException = false
switch subject { switch subject {
case let .vcard(peer, id, data): case let .vcard(peer, id, data):
contactData = .single((peer, id, data)) contactData = .single((peer, id, data))
case let .filter(peer, id, data, _): case let .filter(peer, id, data, _):
contactData = .single((peer, id, data)) contactData = .single((peer, id, data))
case let .create(peer, data, share, _): case let .create(peer, data, share, shareViaExceptionValue, _):
contactData = .single((peer, nil, data)) contactData = .single((peer, nil, data))
isShare = share isShare = share
shareViaException = shareViaExceptionValue
} }
let previousEditingPhoneIds = Atomic<Set<Int64>?>(value: nil) let previousEditingPhoneIds = Atomic<Set<Int64>?>(value: nil)
@ -987,7 +1035,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
completion(peerAndContactData.0, filteredData) completion(peerAndContactData.0, filteredData)
dismissImpl?(true) dismissImpl?(true)
}) })
} else if case let .create(createForPeer, _, _, completion) = subject { } else if case let .create(createForPeer, _, _, _, completion) = subject {
let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents) let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents)
var filteredPhoneNumbers: [DeviceContactPhoneNumberData] = [] var filteredPhoneNumbers: [DeviceContactPhoneNumberData] = []
for phoneNumber in state.phoneNumbers { for phoneNumber in state.phoneNumbers {
@ -1015,16 +1063,18 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
} }
rightNavigationButton = ItemListNavigationButton(content: .text(isShare ? presentationData.strings.Common_Done : presentationData.strings.Compose_Create), style: .bold, enabled: (isShare || !filteredPhoneNumbers.isEmpty) && composedContactData != nil, action: { rightNavigationButton = ItemListNavigationButton(content: .text(isShare ? presentationData.strings.Common_Done : presentationData.strings.Compose_Create), style: .bold, enabled: (isShare || !filteredPhoneNumbers.isEmpty) && composedContactData != nil, action: {
if let composedContactData = composedContactData { if let composedContactData = composedContactData {
var addToPrivacyExceptions = false
updateState { state in updateState { state in
var state = state var state = state
state.savingData = true state.savingData = true
addToPrivacyExceptions = state.addToPrivacyExceptions
return state return state
} }
if let contactDataManager = context.sharedContext.contactDataManager { if let contactDataManager = context.sharedContext.contactDataManager {
switch subject { switch subject {
case let .create(peer, _, share, _): case let .create(peer, _, share, shareViaException, _):
if share, filteredPhoneNumbers.count <= 1, let peer = peer { if share, filteredPhoneNumbers.count <= 1, let peer = peer {
addContactDisposable.set((addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "") addContactDisposable.set((addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|> deliverOnMainQueue).start(error: { _ in |> deliverOnMainQueue).start(error: { _ in
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
}, completed: { }, completed: {
@ -1056,9 +1106,9 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
} }
if filteredPhoneNumbers.count <= 1 { if filteredPhoneNumbers.count <= 1 {
switch subject { switch subject {
case let .create(peer, _, share, _): case let .create(peer, _, share, shareViaException, _):
if share, let peer = peer { if share, let peer = peer {
return addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "") return addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|> mapToSignal { _ -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in |> mapToSignal { _ -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
return .complete() return .complete()
} }
@ -1146,7 +1196,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId) focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId)
} }
let listState = ItemListNodeState(entries: deviceContactInfoEntries(account: context.account, presentationData: presentationData, peer: peerAndContactData.0, isShare: isShare, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones), style: .plain, focusItemTag: focusItemTag) let listState = ItemListNodeState(entries: deviceContactInfoEntries(account: context.account, presentationData: presentationData, peer: peerAndContactData.0, isShare: isShare, shareViaException: shareViaException, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones), style: .plain, focusItemTag: focusItemTag)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }
@ -1269,7 +1319,7 @@ private func addContactToExisting(context: AccountContext, parentController: Vie
let _ = (dataSignal let _ = (dataSignal
|> deliverOnMainQueue).start(next: { peer, stableId in |> deliverOnMainQueue).start(next: { peer, stableId in
guard let stableId = stableId else { guard let stableId = stableId else {
parentController.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: false, completion: { peer, stableId, contactData in parentController.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
})), in: .window(.root)) })), in: .window(.root))
return return
@ -1315,7 +1365,7 @@ func addContactOptionsController(context: AccountContext, peer: Peer?, contactDa
controller.setItemGroups([ controller.setItemGroups([
ActionSheetItemGroup(items: [ ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Profile_CreateNewContact, action: { [weak controller] in ActionSheetButtonItem(title: presentationData.strings.Profile_CreateNewContact, action: { [weak controller] in
controller?.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: peer != nil, completion: { peer, stableId, contactData in controller?.present(deviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: peer != nil, shareViaException: false, completion: { peer, stableId, contactData in
if let peer = peer { if let peer = peer {
} else { } else {

View File

@ -752,7 +752,9 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
requestActivateSearch() requestActivateSearch()
} }
let presentPeerSettings: (PeerId, @escaping () -> Void) -> Void = { peerId, completion in let presentPeerSettings: (PeerId, @escaping () -> Void) -> Void = { [weak self] peerId, completion in
(self?.searchDisplayController?.contentNode as? NotificationExceptionsSearchContainerNode)?.listNode.clearHighlightAnimated(true)
let _ = (context.account.postbox.transaction { transaction -> Peer? in let _ = (context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId) return transaction.getPeer(peerId)
} }
@ -1115,7 +1117,7 @@ private func preparedNotificationExceptionsSearchContainerTransition(theme: Pres
private final class NotificationExceptionsSearchContainerNode: SearchDisplayControllerContentNode { private final class NotificationExceptionsSearchContainerNode: SearchDisplayControllerContentNode {
private let dimNode: ASDisplayNode private let dimNode: ASDisplayNode
private let listNode: ListView let listNode: ListView
private var enqueuedTransitions: [NotificationExceptionsSearchContainerTransition] = [] private var enqueuedTransitions: [NotificationExceptionsSearchContainerTransition] = []
private var hasValidLayout = false private var hasValidLayout = false

View File

@ -267,11 +267,9 @@ private struct NotificationExceptionPeerState : Equatable {
if let notifications = notifications { if let notifications = notifications {
self.selectedSound = notifications.messageSound self.selectedSound = notifications.messageSound
switch notifications.muteState { switch notifications.muteState {
case .muted: case let .muted(until) where until >= Int32.max - 1:
self.mode = .alwaysOff self.mode = .alwaysOff
case .unmuted: default:
self.mode = .alwaysOn
case .default:
self.mode = .alwaysOn self.mode = .alwaysOn
} }
self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn

View File

@ -157,7 +157,7 @@ public class NotificationExceptionsController: ViewController {
} }
@objc private func removeAllPressed() { @objc private func removeAllPressed() {
self.controllerNode self.controllerNode.removeAll()
} }
@objc private func editPressed() { @objc private func editPressed() {

View File

@ -10,7 +10,7 @@ func openAddContact(context: AccountContext, firstName: String = "", lastName: S
switch value { switch value {
case .allowed: case .allowed:
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: []) let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [])
present(deviceContactInfoController(context: context, subject: .create(peer: nil, contactData: contactData, isSharing: false, completion: { peer, stableId, contactData in present(deviceContactInfoController(context: context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
if let peer = peer { if let peer = peer {
if let infoController = peerInfoController(context: context, peer: peer) { if let infoController = peerInfoController(context: context, peer: peer) {
pushController(infoController) pushController(infoController)

File diff suppressed because it is too large Load Diff

View File

@ -735,16 +735,18 @@ private func userInfoEntries(account: Account, presentationData: PresentationDat
return entries return entries
} }
private func getUserPeer(postbox: Postbox, peerId: PeerId) -> Signal<Peer?, NoError> { private func getUserPeer(postbox: Postbox, peerId: PeerId) -> Signal<(Peer?, CachedPeerData?), NoError> {
return postbox.transaction { transaction -> Peer? in return postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
guard let peer = transaction.getPeer(peerId) else { guard let peer = transaction.getPeer(peerId) else {
return nil return (nil, nil)
} }
var resultPeer: Peer?
if let peer = peer as? TelegramSecretChat { if let peer = peer as? TelegramSecretChat {
return transaction.getPeer(peer.regularPeerId) resultPeer = transaction.getPeer(peer.regularPeerId)
} else { } else {
return peer resultPeer = peer
} }
return (resultPeer, resultPeer.flatMap({ transaction.getPeerCachedData(peerId: $0.id) }))
} }
} }
@ -856,7 +858,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} }
} }
}, tapAvatarAction: { }, tapAvatarAction: {
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) |> deliverOnMainQueue).start(next: { peer in let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) |> deliverOnMainQueue).start(next: { peer, _ in
guard let peer = peer else { guard let peer = peer else {
return return
} }
@ -879,12 +881,17 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
openChatImpl?() openChatImpl?()
}, addContact: { }, addContact: {
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, cachedData in
guard let user = peer as? TelegramUser, let contactData = DeviceContactExtendedData(peer: user) else { guard let user = peer as? TelegramUser, let contactData = DeviceContactExtendedData(peer: user) else {
return return
} }
presentControllerImpl?(deviceContactInfoController(context: context, subject: .create(peer: user, contactData: contactData, isSharing: true, completion: { peer, stableId, contactData in var shareViaException = false
if let cachedData = cachedData as? CachedUserData, let peerStatusSettings = cachedData.peerStatusSettings {
shareViaException = peerStatusSettings.contains(.addExceptionWhenAddingContact)
}
presentControllerImpl?(deviceContactInfoController(context: context, subject: .create(peer: user, contactData: contactData, isSharing: true, shareViaException: shareViaException, completion: { peer, stableId, contactData in
if let peer = peer as? TelegramUser { if let peer = peer as? TelegramUser {
if let phone = peer.phone, !phone.isEmpty { if let phone = peer.phone, !phone.isEmpty {
} }
@ -931,7 +938,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
}, openGroupsInCommon: { }, openGroupsInCommon: {
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> take(1) |> take(1)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
guard let peer = peer else { guard let peer = peer else {
return return
} }
@ -941,7 +948,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
}, updatePeerBlocked: { value in }, updatePeerBlocked: { value in
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> take(1) |> take(1)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
guard let peer = peer else { guard let peer = peer else {
return return
} }
@ -1021,7 +1028,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
ActionSheetButtonItem(title: presentationData.strings.UserInfo_DeleteContact, color: .destructive, action: { ActionSheetButtonItem(title: presentationData.strings.UserInfo_DeleteContact, color: .destructive, action: {
dismissAction() dismissAction()
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
guard let peer = peer else { guard let peer = peer else {
return return
} }
@ -1031,12 +1038,33 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} else { } else {
deleteContactFromDevice = .complete() deleteContactFromDevice = .complete()
} }
updatePeerBlockedDisposable.set((
deleteContactPeerInteractively(account: context.account, peerId: peer.id) var deleteSignal = deleteContactPeerInteractively(account: context.account, peerId: peer.id)
|> then( |> then(deleteContactFromDevice)
deleteContactFromDevice
) let progressSignal = Signal<Never, NoError> { subscriber in
).start()) let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil))
presentControllerImpl?(controller, nil)
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.15, queue: Queue.mainQueue())
let progressDisposable = progressSignal.start()
deleteSignal = deleteSignal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
updatePeerBlockedDisposable.set((deleteSignal
|> deliverOnMainQueue).start())
}) })
}) })
]), ]),
@ -1052,7 +1080,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
requestCallImpl() requestCallImpl()
}, openCallMenu: { number in }, openCallMenu: { number in
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
if let peer = peer as? TelegramUser, let peerPhoneNumber = peer.phone, formatPhoneNumber(number) == formatPhoneNumber(peerPhoneNumber) { if let peer = peer as? TelegramUser, let peerPhoneNumber = peer.phone, formatPhoneNumber(number) == formatPhoneNumber(peerPhoneNumber) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = ActionSheetController(presentationTheme: presentationData.theme) let controller = ActionSheetController(presentationTheme: presentationData.theme)
@ -1212,7 +1240,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} }
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> mapToSignal { peer -> Signal<Void, NoError> in |> mapToSignal { peer, _ -> Signal<Void, NoError> in
guard let peer = peer as? TelegramUser, let phone = peer.phone, !phone.isEmpty else { guard let peer = peer as? TelegramUser, let phone = peer.phone, !phone.isEmpty else {
return .complete() return .complete()
} }
@ -1271,7 +1299,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} }
shareContactImpl = { [weak controller] in shareContactImpl = { [weak controller] in
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
if let peer = peer as? TelegramUser, let phone = peer.phone { if let peer = peer as? TelegramUser, let phone = peer.phone {
let contact = TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil) let contact = TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)
let shareController = ShareController(context: context, subject: .media(.standalone(media: contact))) let shareController = ShareController(context: context, subject: .media(.standalone(media: contact)))
@ -1281,7 +1309,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} }
shareMyContactImpl = { [weak controller] in shareMyContactImpl = { [weak controller] in
let _ = (getUserPeer(postbox: context.account.postbox, peerId: context.account.peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: context.account.peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
guard let peer = peer as? TelegramUser, let phone = peer.phone else { guard let peer = peer as? TelegramUser, let phone = peer.phone else {
return return
} }
@ -1377,7 +1405,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
} }
shareBotImpl = { [weak controller] in shareBotImpl = { [weak controller] in
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId) let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer, _ in
if let peer = peer as? TelegramUser, let username = peer.username { if let peer = peer as? TelegramUser, let username = peer.username {
let shareController = ShareController(context: context, subject: .url("https://t.me/\(username)")) let shareController = ShareController(context: context, subject: .url("https://t.me/\(username)"))
controller?.present(shareController, in: .window(.root)) controller?.present(shareController, in: .window(.root))

View File

@ -5,8 +5,8 @@ LottieExamples/LottieExamples.xcodeproj/xcuserdata/
LottieExamples.xcworkspace/xcuserdata/ LottieExamples.xcworkspace/xcuserdata/
Lottie/Lottie.xcodeproj/xcuserdata/ Lottie/Lottie.xcodeproj/xcuserdata/
UserInterfaceState.xcuserstate UserInterfaceState.xcuserstate
xample/lottie-ios.xcodeproj/xcuserdata Example/lottie-ios.xcodeproj/xcuserdata
Lottie.xcodeproj/xcuserdata/ */xcuserdata/*
Example/lottie-ios.xcworkspace/xcuserdata/ Example/lottie-ios.xcworkspace/xcuserdata/
Example/lottie-ios.xcodeproj/xcuserdata/ Example/lottie-ios.xcodeproj/xcuserdata/
.idea/ .idea/

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Lottie.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>Lottie_iOS.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>31</integer>
</dict>
</dict>
</dict>
</plist>