mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-02-19 09:11:48 +00:00
Migrated constructors: starsSubscription, starsSubscriptionPricing, starsTopupOption, starsTransaction, starsTransactionPeer, statsAbsValueAndPrev, statsDateRangeDays, statsGraph, statsGraphAsync, statsGraphError, statsGroupTopAdmin, statsGroupTopInviter, statsGroupTopPoster, statsPercentValue, stickerKeyword, stickerPack, stickerSet, stickerSetCovered, stickerSetFullCovered, stickerSetMultiCovered, stickerSetNoCovered, storiesStealthMode, storyAlbum, storyFwdHeader Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
145 lines
9.3 KiB
Swift
145 lines
9.3 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import TelegramApi
|
|
import SwiftSignalKit
|
|
import MtProtoKit
|
|
|
|
func telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: Int32, thumbVersion: Int32?, sizes: [Api.PhotoSize]) -> (immediateThumbnail: Data?, representations: [TelegramMediaImageRepresentation]) {
|
|
func stickerTypeHint(for type: String) -> TelegramMediaImageRepresentation.TypeHint {
|
|
switch type {
|
|
case "s":
|
|
return .generic
|
|
case "a":
|
|
return .animated
|
|
case "v":
|
|
return .video
|
|
default:
|
|
return .generic
|
|
}
|
|
}
|
|
var immediateThumbnailData: Data?
|
|
var representations: [TelegramMediaImageRepresentation] = []
|
|
for size in sizes {
|
|
switch size {
|
|
case let .photoCachedSize(photoCachedSizeData):
|
|
let (type, w, h) = (photoCachedSizeData.type, photoCachedSizeData.w, photoCachedSizeData.h)
|
|
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
|
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, typeHint: stickerTypeHint(for: type)))
|
|
case let .photoSize(photoSizeData):
|
|
let (type, w, h) = (photoSizeData.type, photoSizeData.w, photoSizeData.h)
|
|
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
|
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, typeHint: stickerTypeHint(for: type)))
|
|
case let .photoSizeProgressive(photoSizeProgressiveData):
|
|
let (type, w, h, sizes) = (photoSizeProgressiveData.type, photoSizeProgressiveData.w, photoSizeProgressiveData.h, photoSizeProgressiveData.sizes)
|
|
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
|
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, typeHint: stickerTypeHint(for: type)))
|
|
case let .photoPathSize(photoPathSizeData):
|
|
let data = photoPathSizeData.bytes
|
|
immediateThumbnailData = data.makeData()
|
|
case .photoStrippedSize:
|
|
break
|
|
case .photoSizeEmpty:
|
|
break
|
|
}
|
|
}
|
|
return (immediateThumbnailData, representations)
|
|
}
|
|
|
|
extension StickerPackCollectionInfo {
|
|
convenience init(apiSet: Api.StickerSet, namespace: ItemCollectionId.Namespace) {
|
|
switch apiSet {
|
|
case let .stickerSet(stickerSetData):
|
|
let (flags, _, id, accessHash, title, shortName, thumbs, thumbDcId, thumbVersion, thumbDocumentId, count, nHash) = (stickerSetData.flags, stickerSetData.installedDate, stickerSetData.id, stickerSetData.accessHash, stickerSetData.title, stickerSetData.shortName, stickerSetData.thumbs, stickerSetData.thumbDcId, stickerSetData.thumbVersion, stickerSetData.thumbDocumentId, stickerSetData.count, stickerSetData.hash)
|
|
var setFlags: StickerPackCollectionInfoFlags = StickerPackCollectionInfoFlags()
|
|
if (flags & (1 << 2)) != 0 {
|
|
setFlags.insert(.isOfficial)
|
|
}
|
|
if (flags & (1 << 3)) != 0 {
|
|
setFlags.insert(.isMasks)
|
|
}
|
|
if (flags & (1 << 7)) != 0 {
|
|
setFlags.insert(.isEmoji)
|
|
}
|
|
if (flags & (1 << 9)) != 0 {
|
|
setFlags.insert(.isCustomTemplateEmoji)
|
|
}
|
|
if (flags & (1 << 10)) != 0 {
|
|
setFlags.insert(.isAvailableAsChannelStatus)
|
|
}
|
|
if (flags & (1 << 11)) != 0 {
|
|
setFlags.insert(.isCreator)
|
|
}
|
|
|
|
var thumbnailRepresentation: TelegramMediaImageRepresentation?
|
|
var immediateThumbnailData: Data?
|
|
if let thumbs = thumbs, let thumbDcId = thumbDcId {
|
|
let (data, representations) = telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: thumbDcId, thumbVersion: thumbVersion, sizes: thumbs)
|
|
thumbnailRepresentation = representations.first
|
|
immediateThumbnailData = data
|
|
}
|
|
|
|
self.init(id: ItemCollectionId(namespace: namespace, id: id), flags: setFlags, accessHash: accessHash, title: title, shortName: shortName, thumbnail: thumbnailRepresentation, thumbnailFileId: thumbDocumentId, immediateThumbnailData: immediateThumbnailData, hash: nHash, count: count)
|
|
}
|
|
}
|
|
}
|
|
|
|
func _internal_stickerPacksAttachedToMedia(account: Account, media: AnyMediaReference) -> Signal<[StickerPackReference], NoError> {
|
|
let inputMedia: Api.InputStickeredMedia
|
|
let resourceReference: MediaResourceReference
|
|
if let imageReference = media.concrete(TelegramMediaImage.self), let reference = imageReference.media.reference, case let .cloud(imageId, accessHash, fileReference) = reference, let representation = largestImageRepresentation(imageReference.media.representations) {
|
|
inputMedia = .inputStickeredMediaPhoto(.init(id: Api.InputPhoto.inputPhoto(.init(id: imageId, accessHash: accessHash, fileReference: Buffer(data: fileReference ?? Data())))))
|
|
resourceReference = imageReference.resourceReference(representation.resource)
|
|
} else if let fileReference = media.concrete(TelegramMediaFile.self), let resource = fileReference.media.resource as? CloudDocumentMediaResource {
|
|
inputMedia = .inputStickeredMediaDocument(.init(id: Api.InputDocument.inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())))))
|
|
resourceReference = fileReference.resourceReference(fileReference.media.resource)
|
|
} else {
|
|
return .single([])
|
|
}
|
|
let accountPeerId = account.peerId
|
|
return account.network.request(Api.functions.messages.getAttachedStickers(media: inputMedia))
|
|
|> `catch` { _ -> Signal<[Api.StickerSetCovered], MTRpcError> in
|
|
return revalidateMediaResourceReference(accountPeerId: accountPeerId, postbox: account.postbox, network: account.network, revalidationContext: account.mediaReferenceRevalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: resourceReference, preferBackgroundReferenceRevalidation: false, continueInBackground: false), resource: resourceReference.resource)
|
|
|> mapError { _ -> MTRpcError in
|
|
return MTRpcError(errorCode: 500, errorDescription: "Internal")
|
|
}
|
|
|> mapToSignal { reference -> Signal<[Api.StickerSetCovered], MTRpcError> in
|
|
let inputMedia: Api.InputStickeredMedia
|
|
if let resource = reference.updatedResource as? TelegramCloudMediaResourceWithFileReference, let updatedReference = resource.fileReference {
|
|
if let imageReference = media.concrete(TelegramMediaImage.self), let reference = imageReference.media.reference, case let .cloud(imageId, accessHash, _) = reference, let _ = largestImageRepresentation(imageReference.media.representations) {
|
|
inputMedia = .inputStickeredMediaPhoto(.init(id: Api.InputPhoto.inputPhoto(.init(id: imageId, accessHash: accessHash, fileReference: Buffer(data: updatedReference)))))
|
|
} else if let fileReference = media.concrete(TelegramMediaFile.self), let resource = fileReference.media.resource as? CloudDocumentMediaResource {
|
|
inputMedia = .inputStickeredMediaDocument(.init(id: Api.InputDocument.inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: updatedReference)))))
|
|
} else {
|
|
return .single([])
|
|
}
|
|
return account.network.request(Api.functions.messages.getAttachedStickers(media: inputMedia))
|
|
} else {
|
|
return .single([])
|
|
}
|
|
}
|
|
|> `catch` { _ -> Signal<[Api.StickerSetCovered], MTRpcError> in
|
|
return .single([])
|
|
}
|
|
}
|
|
|> map { result -> [StickerPackReference] in
|
|
return result.map { pack in
|
|
let set: Api.StickerSet
|
|
switch pack {
|
|
case let .stickerSetCovered(stickerSetCoveredData):
|
|
set = stickerSetCoveredData.set
|
|
case let .stickerSetMultiCovered(stickerSetMultiCoveredData):
|
|
set = stickerSetMultiCoveredData.set
|
|
case let .stickerSetFullCovered(stickerSetFullCoveredData):
|
|
set = stickerSetFullCoveredData.set
|
|
case let .stickerSetNoCovered(stickerSetNoCoveredData):
|
|
set = stickerSetNoCoveredData.set
|
|
}
|
|
let info = StickerPackCollectionInfo(apiSet: set, namespace: Namespaces.ItemCollection.CloudStickerPacks)
|
|
return .id(id: info.id.id, accessHash: info.accessHash)
|
|
}
|
|
}
|
|
|> `catch` { _ -> Signal<[StickerPackReference], NoError> in
|
|
return .single([])
|
|
}
|
|
}
|