From 66a614a9a49570e5c18b8ba977ca7fd13a78fdd7 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 20 Aug 2025 22:31:58 +0400 Subject: [PATCH] Update API --- submodules/TelegramApi/Sources/Api0.swift | 4 +-- submodules/TelegramApi/Sources/Api35.swift | 28 ++++++++++----- submodules/TelegramApi/Sources/Api36.swift | 28 ++++++++++----- submodules/TelegramApi/Sources/Api39.swift | 20 +++++++++++ .../Network/FetchedMediaResource.swift | 36 +++++++++++++++++++ .../SyncCore/SyncCore_MediaReference.swift | 36 ++++++++++++++++++- .../TelegramEngine/Payments/StarGifts.swift | 4 +-- .../TelegramEngine/Peers/SavedMusic.swift | 25 +++++++++++++ .../TelegramCore/Sources/WebpagePreview.swift | 8 ++--- 9 files changed, 162 insertions(+), 27 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 7221744aee..4cd9dba044 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -1430,7 +1430,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[870003448] = { return Api.messages.TranslatedText.parse_translateResult($0) } dict[1218005070] = { return Api.messages.VotesList.parse_votesList($0) } dict[-44166467] = { return Api.messages.WebPage.parse_webPage($0) } - dict[-1254192351] = { return Api.messages.WebPagePreview.parse_webPagePreview($0) } + dict[-1936029524] = { return Api.messages.WebPagePreview.parse_webPagePreview($0) } dict[1042605427] = { return Api.payments.BankCardData.parse_bankCardData($0) } dict[675942550] = { return Api.payments.CheckedGiftCode.parse_checkedGiftCode($0) } dict[-1730811363] = { return Api.payments.ConnectedStarRefBots.parse_connectedStarRefBots($0) } @@ -1458,7 +1458,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) } dict[1822222573] = { return Api.payments.StarsStatus.parse_starsStatus($0) } dict[-1261053863] = { return Api.payments.SuggestedStarRefBots.parse_suggestedStarRefBots($0) } - dict[-895289845] = { return Api.payments.UniqueStarGift.parse_uniqueStarGift($0) } + dict[1097619176] = { return Api.payments.UniqueStarGift.parse_uniqueStarGift($0) } dict[1362093126] = { return Api.payments.UniqueStarGiftValueInfo.parse_uniqueStarGiftValueInfo($0) } dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) } dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) } diff --git a/submodules/TelegramApi/Sources/Api35.swift b/submodules/TelegramApi/Sources/Api35.swift index 1c8af79156..de66e60088 100644 --- a/submodules/TelegramApi/Sources/Api35.swift +++ b/submodules/TelegramApi/Sources/Api35.swift @@ -812,16 +812,21 @@ public extension Api.messages { } public extension Api.messages { indirect enum WebPagePreview: TypeConstructorDescription { - case webPagePreview(media: Api.MessageMedia, users: [Api.User]) + case webPagePreview(media: Api.MessageMedia, chats: [Api.Chat], users: [Api.User]) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .webPagePreview(let media, let users): + case .webPagePreview(let media, let chats, let users): if boxed { - buffer.appendInt32(-1254192351) + buffer.appendInt32(-1936029524) } media.serialize(buffer, true) buffer.appendInt32(481674261) + buffer.appendInt32(Int32(chats.count)) + for item in chats { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) buffer.appendInt32(Int32(users.count)) for item in users { item.serialize(buffer, true) @@ -832,8 +837,8 @@ public extension Api.messages { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .webPagePreview(let media, let users): - return ("webPagePreview", [("media", media as Any), ("users", users as Any)]) + case .webPagePreview(let media, let chats, let users): + return ("webPagePreview", [("media", media as Any), ("chats", chats as Any), ("users", users as Any)]) } } @@ -842,14 +847,19 @@ public extension Api.messages { if let signature = reader.readInt32() { _1 = Api.parse(reader, signature: signature) as? Api.MessageMedia } - var _2: [Api.User]? + var _2: [Api.Chat]? if let _ = reader.readInt32() { - _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) + } + var _3: [Api.User]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) } let _c1 = _1 != nil let _c2 = _2 != nil - if _c1 && _c2 { - return Api.messages.WebPagePreview.webPagePreview(media: _1!, users: _2!) + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.messages.WebPagePreview.webPagePreview(media: _1!, chats: _2!, users: _3!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api36.swift b/submodules/TelegramApi/Sources/Api36.swift index 1c2792b3f4..393425edcb 100644 --- a/submodules/TelegramApi/Sources/Api36.swift +++ b/submodules/TelegramApi/Sources/Api36.swift @@ -718,16 +718,21 @@ public extension Api.payments { } public extension Api.payments { enum UniqueStarGift: TypeConstructorDescription { - case uniqueStarGift(gift: Api.StarGift, users: [Api.User]) + case uniqueStarGift(gift: Api.StarGift, chats: [Api.Chat], users: [Api.User]) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .uniqueStarGift(let gift, let users): + case .uniqueStarGift(let gift, let chats, let users): if boxed { - buffer.appendInt32(-895289845) + buffer.appendInt32(1097619176) } gift.serialize(buffer, true) buffer.appendInt32(481674261) + buffer.appendInt32(Int32(chats.count)) + for item in chats { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) buffer.appendInt32(Int32(users.count)) for item in users { item.serialize(buffer, true) @@ -738,8 +743,8 @@ public extension Api.payments { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .uniqueStarGift(let gift, let users): - return ("uniqueStarGift", [("gift", gift as Any), ("users", users as Any)]) + case .uniqueStarGift(let gift, let chats, let users): + return ("uniqueStarGift", [("gift", gift as Any), ("chats", chats as Any), ("users", users as Any)]) } } @@ -748,14 +753,19 @@ public extension Api.payments { if let signature = reader.readInt32() { _1 = Api.parse(reader, signature: signature) as? Api.StarGift } - var _2: [Api.User]? + var _2: [Api.Chat]? if let _ = reader.readInt32() { - _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) + } + var _3: [Api.User]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) } let _c1 = _1 != nil let _c2 = _2 != nil - if _c1 && _c2 { - return Api.payments.UniqueStarGift.uniqueStarGift(gift: _1!, users: _2!) + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.payments.UniqueStarGift.uniqueStarGift(gift: _1!, chats: _2!, users: _3!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api39.swift b/submodules/TelegramApi/Sources/Api39.swift index 7ea798e826..b585464e2d 100644 --- a/submodules/TelegramApi/Sources/Api39.swift +++ b/submodules/TelegramApi/Sources/Api39.swift @@ -12323,6 +12323,26 @@ public extension Api.functions.users { }) } } +public extension Api.functions.users { + static func getSavedMusicByID(id: Api.InputUser, documents: [Api.InputDocument]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(1970513129) + id.serialize(buffer, true) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(documents.count)) + for item in documents { + item.serialize(buffer, true) + } + return (FunctionDescription(name: "users.getSavedMusicByID", parameters: [("id", String(describing: id)), ("documents", String(describing: documents))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.users.SavedMusic? in + let reader = BufferReader(buffer) + var result: Api.users.SavedMusic? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.users.SavedMusic + } + return result + }) + } +} public extension Api.functions.users { static func getUsers(id: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.User]>) { let buffer = Buffer() diff --git a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift index 2cc69b8557..40fd07692b 100644 --- a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift +++ b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift @@ -334,6 +334,7 @@ private enum MediaReferenceRevalidationKey: Hashable { case customEmoji(fileId: Int64) case story(peer: PeerReference, id: Int32) case starsTransaction(transaction: StarsTransactionReference) + case savedMusic(peer: PeerReference, fileId: Int64) } private final class MediaReferenceRevalidationItemContext { @@ -794,6 +795,33 @@ final class MediaReferenceRevalidationContext { } } + func savedMusic(accountPeerId: PeerId, postbox: Postbox, network: Network, background: Bool, peer: PeerReference, media: Media) -> Signal { + guard let file = media as? TelegramMediaFile else { + return .fail(.generic) + } + return self.genericItem(key: .savedMusic(peer: peer, fileId: file.fileId.id), background: background, request: { next, error in + return (_internal_getSavedMusicById(postbox: postbox, network: network, peer: peer, file: file) + |> castError(RevalidateMediaReferenceError.self) + |> mapToSignal { result -> Signal in + if let result { + return .single(result) + } else { + return .fail(.generic) + } + }).start(next: { value in + next(value) + }, error: { _ in + error(.generic) + }) + }) |> mapToSignal { next -> Signal in + if let next = next as? TelegramMediaFile { + return .single(next) + } else { + return .fail(.generic) + } + } + } + func notificationSoundList(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> { return self.genericItem(key: .notificationSoundList, background: background, request: { next, error in return (requestNotificationSoundList(network: network, hash: 0) @@ -993,6 +1021,14 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n } return .fail(.generic) } + case let .savedMusic(peer, media): + return revalidationContext.savedMusic(accountPeerId: accountPeerId, postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, peer: peer, media: media) + |> mapToSignal { result -> Signal in + if let updatedResource = findUpdatedMediaResource(media: result, previousMedia: media, resource: resource) { + return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil)) + } + return .fail(.generic) + } case let .standalone(media): if let file = media as? TelegramMediaFile { for attribute in file.attributes { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_MediaReference.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_MediaReference.swift index d0f1e0a6bc..d94f674edb 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_MediaReference.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_MediaReference.swift @@ -277,6 +277,7 @@ public enum AnyMediaReference: Equatable { case customEmoji(media: Media) case story(peer: PeerReference, id: Int32, media: Media) case starsTransaction(transaction: StarsTransactionReference, media: Media) + case savedMusic(peer: PeerReference, media: Media) public static func ==(lhs: AnyMediaReference, rhs: AnyMediaReference) -> Bool { switch lhs { @@ -352,6 +353,12 @@ public enum AnyMediaReference: Equatable { } else { return false } + case let .savedMusic(lhsPeer, lhsMedia): + if case let .savedMusic(rhsPeer, rhsMedia) = rhs, lhsPeer == rhsPeer, lhsMedia.isEqual(to: rhsMedia) { + return true + } else { + return false + } } } @@ -381,6 +388,8 @@ public enum AnyMediaReference: Equatable { return nil case .starsTransaction: return nil + case .savedMusic: + return nil } } @@ -434,6 +443,10 @@ public enum AnyMediaReference: Equatable { if let media = media as? T { return .starsTransaction(transaction: transaction, media: media) } + case let .savedMusic(peer, media): + if let media = media as? T { + return .savedMusic(peer: peer, media: media) + } } return nil } @@ -464,6 +477,8 @@ public enum AnyMediaReference: Equatable { return media case let .starsTransaction(_, media): return media + case let .savedMusic(_, media): + return media } } @@ -493,6 +508,8 @@ public enum AnyMediaReference: Equatable { return .story(peer: peer, id: id, media: media) case let .starsTransaction(transaction, _): return .starsTransaction(transaction: transaction, media: media) + case let .savedMusic(peer, _): + return .savedMusic(peer: peer, media: media) } } @@ -593,6 +610,7 @@ public enum MediaReference { case customEmoji case story case starsTransaction + case savedMusic } case standalone(media: T) @@ -607,6 +625,7 @@ public enum MediaReference { case customEmoji(media: T) case story(peer: PeerReference, id: Int32, media: T) case starsTransaction(transaction: StarsTransactionReference, media: T) + case savedMusic(peer: PeerReference, media: T) public init?(decoder: PostboxDecoder) { guard let caseIdValue = decoder.decodeOptionalInt32ForKey("_r"), let caseId = CodingCase(rawValue: caseIdValue) else { @@ -681,6 +700,12 @@ public enum MediaReference { return nil } self = .starsTransaction(transaction: transaction, media: media) + case .savedMusic: + let peer = decoder.decodeObjectForKey("pr", decoder: { PeerReference(decoder: $0) }) as! PeerReference + guard let media = decoder.decodeObjectForKey("m") as? T else { + return nil + } + self = .savedMusic(peer: peer, media: media) } } @@ -730,9 +755,12 @@ public enum MediaReference { encoder.encodeInt32(CodingCase.starsTransaction.rawValue, forKey: "_r") encoder.encodeObject(transaction, forKey: "tr") encoder.encodeObject(media, forKey: "m") + case let .savedMusic(peer, media): + encoder.encodeInt32(CodingCase.savedMusic.rawValue, forKey: "_r") + encoder.encodeObject(peer, forKey: "pr") + encoder.encodeObject(media, forKey: "m") } } - public var abstract: AnyMediaReference { switch self { @@ -760,6 +788,8 @@ public enum MediaReference { return .story(peer: peer, id: id, media: media) case let .starsTransaction(transaction, media): return .starsTransaction(transaction: transaction, media: media) + case let .savedMusic(peer, media): + return .savedMusic(peer: peer, media: media) } } @@ -793,6 +823,8 @@ public enum MediaReference { return media case let .starsTransaction(_, media): return media + case let .savedMusic(_, media): + return media } } @@ -822,6 +854,8 @@ public enum MediaReference { return .story(peer: peer, id: id, media: media) case let .starsTransaction(transaction, _): return .starsTransaction(transaction: transaction, media: media) + case let .savedMusic(peer, _): + return .savedMusic(peer: peer, media: media) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift index e3f261b9e9..09f9c336f1 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift @@ -2560,9 +2560,9 @@ func _internal_getUniqueStarGift(account: Account, slug: String) -> Signal mapToSignal { result -> Signal in if let result = result { switch result { - case let .uniqueStarGift(gift, users): + case let .uniqueStarGift(gift, chats, users): return account.postbox.transaction { transaction in - let parsedPeers = AccumulatedPeers(users: users) + let parsedPeers = AccumulatedPeers(chats: chats, users: users) updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers) guard case let .unique(uniqueGift) = StarGift(apiStarGift: gift) else { return nil diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/SavedMusic.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SavedMusic.swift index f2fcbd21a9..a290211e03 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/SavedMusic.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SavedMusic.swift @@ -49,6 +49,31 @@ public final class SavedMusicIdsList: Codable, Equatable { } } +func _internal_getSavedMusicById(postbox: Postbox, network: Network, peer: PeerReference, file: TelegramMediaFile) -> Signal { + let inputUser = peer.inputUser + guard let inputUser, let resource = file.resource as? CloudDocumentMediaResource else { + return .single(nil) + } + return network.request(Api.functions.users.getSavedMusicByID(id: inputUser, documents: [.inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))])) + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> map { result -> TelegramMediaFile? in + if let result { + switch result { + case let .savedMusic(_, documents): + if let file = documents.first.flatMap({ telegramMediaFileFromApiDocument($0, altDocuments: nil) }) { + return file + } + default: + break + } + } + return nil + } +} + func _internal_savedMusicIds(postbox: Postbox) -> Signal?, NoError> { let viewKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.savedMusicIds()])) return postbox.combinedView(keys: [viewKey]) diff --git a/submodules/TelegramCore/Sources/WebpagePreview.swift b/submodules/TelegramCore/Sources/WebpagePreview.swift index 7109d300d1..dbc8440822 100644 --- a/submodules/TelegramCore/Sources/WebpagePreview.swift +++ b/submodules/TelegramCore/Sources/WebpagePreview.swift @@ -157,7 +157,7 @@ public func webpagePreviewWithProgress(account: Account, urls: [String], webpage return account.network.requestWithAdditionalInfo(Api.functions.messages.getWebPagePreview(flags: 0, message: urls.joined(separator: " "), entities: nil), info: .progress) |> `catch` { _ -> Signal, NoError> in - return .single(.result(.webPagePreview(media: .messageMediaEmpty, users: []))) + return .single(.result(.webPagePreview(media: .messageMediaEmpty, chats: [], users: []))) } |> mapToSignal { result -> Signal in switch result { @@ -170,17 +170,17 @@ public func webpagePreviewWithProgress(account: Account, urls: [String], webpage return .complete() } case let .result(result): - if case let .webPagePreview(result, _) = result, let preCachedResources = result.preCachedResources { + if case let .webPagePreview(result, _, _) = result, let preCachedResources = result.preCachedResources { for (resource, data) in preCachedResources { account.postbox.mediaBox.storeResourceData(resource.id, data: data) } } switch result { - case let .webPagePreview(media, users): + case let .webPagePreview(media, chats, users): switch media { case let .messageMediaWebPage(_, webpage): return account.postbox.transaction { transaction -> Signal in - let peers = AccumulatedPeers(users: users) + let peers = AccumulatedPeers(chats: chats, users: users) updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers) if let media = telegramMediaWebpageFromApiWebpage(webpage), let url = media.content.url {