Serialization update

This commit is contained in:
Isaac 2025-02-14 19:11:58 +04:00
parent f370102e44
commit 6c4070eb52
98 changed files with 1332 additions and 759 deletions

View File

@ -100,12 +100,12 @@ public final class AvatarVideoNode: ASDisplayNode {
} else {
let itemNativeFitSize = self.internalSize.width > 100.0 ? CGSize(width: 192.0, height: 192.0) : CGSize(width: 64.0, height: 64.0)
let animationData = EntityKeyboardAnimationData(file: animationFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(animationFile))
let itemLayer = EmojiKeyboardItemLayer(
item: EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: animationFile,
itemFile: TelegramMediaFile.Accessor(animationFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
@ -185,7 +185,7 @@ public final class AvatarVideoNode: ASDisplayNode {
self.fileDisposable.set((self.context.engine.stickers.loadedStickerPack(reference: packReference, forceActualized: false)
|> map { pack -> TelegramMediaFile? in
if case let .result(_, items, _) = pack, let item = items.first(where: { $0.file.fileId.id == fileId }) {
return item.file
return item.file._parse()
}
return nil
}

View File

@ -125,8 +125,8 @@ public final class ReactionImageNode: ASDisplayNode {
if let availableReactions = availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
file = availableReaction.staticIcon
animationFile = availableReaction.centerAnimation
file = availableReaction.staticIcon._parse()
animationFile = availableReaction.centerAnimation?._parse()
break
}
}

View File

@ -149,7 +149,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if let availableReactions = availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
self.file = availableReaction.centerAnimation
self.file = availableReaction.centerAnimation?._parse()
self.updateReactionLayer()
break
}
@ -168,7 +168,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if let availableReactions = availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
self.file = availableReaction.centerAnimation
self.file = availableReaction.centerAnimation?._parse()
self.updateReactionLayer()
break
}
@ -567,7 +567,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if let availableReactions = self.availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
self.file = availableReaction.centerAnimation
self.file = availableReaction.centerAnimation?._parse()
self.updateReactionLayer()
self.updateReactionAccentColor(theme: presentationData.theme)
break
@ -588,7 +588,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if let availableReactions = self.availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
self.file = availableReaction.centerAnimation
self.file = availableReaction.centerAnimation?._parse()
self.updateReactionLayer()
self.updateReactionAccentColor(theme: presentationData.theme)
break

View File

@ -134,7 +134,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return DebugControllerSection.web.rawValue
case .keepChatNavigationStack, .skipReadHistory, .dustEffect, .crashOnSlowQueries, .crashOnMemoryPressure:
return DebugControllerSection.experiments.rawValue
case .clearTips, .resetNotifications, .crash, .fillLocalSavedMessageCache, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .resetTagHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .storiesExperiment, .storiesJpegExperiment, .playlistPlayback, .enableQuickReactionSwitch, .experimentalCompatibility, .enableDebugDataDisplay, .rippleEffect, .browserExperiment, .localTranscription, .enableReactionOverrides, .restorePurchases, .disableReloginTokens, .liveStreamV2, .experimentalCallMute, .conferenceCalls, .playerV2, .devRequests, .fakeAds, .enableLocalTranslation:
case .clearTips, .resetNotifications, .crash, .fillLocalSavedMessageCache, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .resetTagHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .storiesExperiment, .storiesJpegExperiment, .playlistPlayback, .enableQuickReactionSwitch, .experimentalCompatibility, .enableDebugDataDisplay, .rippleEffect, .browserExperiment, .localTranscription, .enableReactionOverrides, .restorePurchases, .disableReloginTokens, .liveStreamV2, .experimentalCallMute, .playerV2, .devRequests, .fakeAds, .enableLocalTranslation:
return DebugControllerSection.experiments.rawValue
case .logTranslationRecognition, .resetTranslationStates:
return DebugControllerSection.translation.rawValue
@ -251,8 +251,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return 51
case .experimentalCallMute:
return 52
case .conferenceCalls:
return 53
case .playerV2:
return 54
case .devRequests:
@ -1351,16 +1349,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
})
}).start()
})
case let .conferenceCalls(value):
return ItemListSwitchItem(presentationData: presentationData, title: "Conference [WIP]", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
settings.conferenceCalls = value
return PreferencesEntry(settings)
})
}).start()
})
case let .playerV2(value):
return ItemListSwitchItem(presentationData: presentationData, title: "PlayerV2", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
@ -1558,7 +1546,6 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present
entries.append(.liveStreamV2(experimentalSettings.liveStreamV2))
entries.append(.experimentalCallMute(experimentalSettings.experimentalCallMute))
entries.append(.conferenceCalls(experimentalSettings.conferenceCalls))
entries.append(.playerV2(experimentalSettings.playerV2))
entries.append(.devRequests(experimentalSettings.devRequests))

View File

@ -245,7 +245,7 @@ public class DrawingReactionEntityView: DrawingStickerEntityView {
var animation: TelegramMediaFile?
for reaction in availableReactions.reactions {
if reaction.value == updateReaction.reaction {
animation = reaction.selectAnimation
animation = reaction.selectAnimation._parse()
break
}
}
@ -274,7 +274,7 @@ public class DrawingReactionEntityView: DrawingStickerEntityView {
var animation: TelegramMediaFile?
for reaction in availableReactions.reactions {
if reaction.value == updateReaction.reaction {
animation = reaction.selectAnimation
animation = reaction.selectAnimation._parse()
break
}
}

View File

@ -619,7 +619,7 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
menuItems = [
.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController, let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.sendSticker?(.standalone(media: item.file), animationNode.view, animationNode.bounds)
let _ = strongSelf.sendSticker?(.standalone(media: item.file._parse()), animationNode.view, animationNode.bounds)
}
f(.default)
})),
@ -627,11 +627,11 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
f(.default)
if let strongSelf = self {
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file._parse(), saved: !isStarred)
|> deliverOnMainQueue).start(next: { result in
switch result {
case .generic:
strongSelf.controller?.presentInGlobalOverlay(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: nil, text: !isStarred ? strongSelf.presentationData.strings.Conversation_StickerAddedToFavorites : strongSelf.presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), with: nil)
strongSelf.controller?.presentInGlobalOverlay(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: nil, text: !isStarred ? strongSelf.presentationData.strings.Conversation_StickerAddedToFavorites : strongSelf.presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), with: nil)
case let .limitExceeded(limit, premiumLimit):
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: strongSelf.context.currentAppConfiguration.with { $0 })
let text: String
@ -640,7 +640,7 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
} else {
text = strongSelf.presentationData.strings.Premium_MaxFavedStickersText("\(premiumLimit)").string
}
strongSelf.controller?.presentInGlobalOverlay(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: strongSelf.presentationData.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
strongSelf.controller?.presentInGlobalOverlay(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: strongSelf.presentationData.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
if let strongSelf = self {
if case .info = action {
let controller = PremiumIntroScreen(context: strongSelf.context, source: .savedStickers)
@ -658,7 +658,7 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
f(.default)
if let strongSelf = self {
loop: for attribute in item.file.attributes {
loop: for attribute in item.file._parse().attributes {
switch attribute {
case let .Sticker(_, packReference, _):
if let packReference = packReference {
@ -692,7 +692,7 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
}
}))
]
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file), menu: menuItems, openPremiumIntro: { [weak self] in
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file._parse()), menu: menuItems, openPremiumIntro: { [weak self] in
guard let strongSelf = self else {
return
}
@ -1508,7 +1508,7 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode {
return (itemNode, StickerPreviewPeekItem.found(stickerItem))
} else if let itemNode = itemNode as? StickerPaneSearchGlobalItemNode {
if let (node, item) = itemNode.itemAt(point: self.view.convert(point, to: itemNode.view)) {
return (node, StickerPreviewPeekItem.pack(item.file))
return (node, StickerPreviewPeekItem.pack(item.file._parse()))
}
}
}

View File

@ -112,7 +112,8 @@ final class TrendingTopItemNode: ASDisplayNode {
}
func setup(account: Account, item: StickerPackItem, itemSize: CGSize, synchronousLoads: Bool) {
self.file = item.file
let file = item.file._parse()
self.file = file
self.itemSize = itemSize
if item.file.isAnimatedSticker || item.file.isVideoSticker {
@ -134,23 +135,23 @@ final class TrendingTopItemNode: ASDisplayNode {
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
if item.file.isVideoSticker {
self.imageNode.setSignal(chatMessageSticker(postbox: account.postbox, userLocation: .other, file: item.file, small: false, synchronousLoad: synchronousLoads))
self.imageNode.setSignal(chatMessageSticker(postbox: account.postbox, userLocation: .other, file: file, small: false, synchronousLoad: synchronousLoads))
} else {
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, userLocation: .other, file: item.file, small: false, size: fittedDimensions, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, userLocation: .other, file: file, small: false, size: fittedDimensions, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads)
}
animationNode.started = { [weak self] in
self?.imageNode.alpha = 0.0
}
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start())
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: file.resource, isVideo: file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(file), resource: file.resource).start())
} else {
self.imageNode.setSignal(chatMessageSticker(account: account, userLocation: .other, file: item.file, small: true, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads)
self.imageNode.setSignal(chatMessageSticker(account: account, userLocation: .other, file: file, small: true, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads)
if let currentAnimationNode = self.animationNode {
self.animationNode = nil
currentAnimationNode.removeFromSupernode()
}
self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start())
self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(file), resource: chatMessageStickerResource(file: file, small: true)).start())
}
}

View File

@ -495,12 +495,13 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
}
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: item.packInfo.id.id, accessHash: item.packInfo.accessHash), resource: thumbnail.resource)
} else if let item = item.topItem {
if item.file.isAnimatedSticker || item.file.isVideoSticker {
thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker, item.file.isCustomTemplateEmoji)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
let itemFile = item.file._parse()
if itemFile.isAnimatedSticker || itemFile.isVideoSticker {
thumbnailItem = .animated(itemFile.resource, itemFile.dimensions ?? PixelDimensions(width: 100, height: 100), itemFile.isVideoSticker, itemFile.isCustomTemplateEmoji)
resourceReference = MediaResourceReference.media(media: .standalone(media: itemFile), resource: itemFile.resource)
} else if let dimensions = itemFile.dimensions, let resource = chatMessageStickerResource(file: itemFile, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
resourceReference = MediaResourceReference.media(media: .standalone(media: itemFile), resource: resource)
}
}
@ -848,7 +849,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
imageSize = PixelDimensions(width: 100, height: 100)
}
immediateThumbnailData = data
} else if let data = item.topItem?.file.immediateThumbnailData {
} else if let data = item.topItem?.file._parse().immediateThumbnailData {
immediateThumbnailData = data
}

View File

@ -48,7 +48,7 @@ final class AvatarEditorPreviewView: UIView {
var files: [TelegramMediaFile] = []
for item in view.items.prefix(8) {
if let mediaItem = item.contents.get(RecentMediaItem.self) {
let file = mediaItem.media
let file = mediaItem.media._parse()
files.append(file)
self.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())

View File

@ -42,19 +42,9 @@ public struct ItemCollectionViewEntry {
}
}
public struct RawItemCollectionViewEntry {
public let index: ItemCollectionViewEntryIndex
public let data: Data
private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, lowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [ItemCollectionViewEntry] {
public init(index: ItemCollectionViewEntryIndex, data: Data) {
self.index = index
self.data = data
}
}
private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, lowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [RawItemCollectionViewEntry] {
var entries: [RawItemCollectionViewEntry] = []
var entries: [ItemCollectionViewEntry] = []
var currentCollectionIndex = collectionIndex
var currentCollectionId = collectionId
@ -85,9 +75,9 @@ private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collect
return entries
}
private func fetchHigherEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, higherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [RawItemCollectionViewEntry] {
private func fetchHigherEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, higherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [ItemCollectionViewEntry] {
var entries: [RawItemCollectionViewEntry] = []
var entries: [ItemCollectionViewEntry] = []
var currentCollectionIndex = collectionIndex
var currentCollectionId = collectionId
@ -125,11 +115,11 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?,
fetchLowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem],
higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?,
fetchHigherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> ([RawItemCollectionViewEntry], RawItemCollectionViewEntry?, RawItemCollectionViewEntry?) {
var lowerEntries: [RawItemCollectionViewEntry] = []
var upperEntries: [RawItemCollectionViewEntry] = []
var lower: RawItemCollectionViewEntry?
var upper: RawItemCollectionViewEntry?
fetchHigherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> ([ItemCollectionViewEntry], ItemCollectionViewEntry?, ItemCollectionViewEntry?) {
var lowerEntries: [ItemCollectionViewEntry] = []
var upperEntries: [ItemCollectionViewEntry] = []
var lower: ItemCollectionViewEntry?
var upper: ItemCollectionViewEntry?
let selectedAroundIndex: ItemCollectionViewEntryIndex
if let aroundIndex = aroundIndex, let aroundCollectionIndex = collectionIndexById(aroundIndex.collectionId) {
@ -163,7 +153,7 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
}
if lowerEntries.count != 0 && lowerEntries.count + upperEntries.count < count {
var additionalLowerEntries: [RawItemCollectionViewEntry] = fetchLowerEntries(namespaces: namespaces, collectionId: lowerEntries.last!.index.collectionId, collectionIndex: lowerEntries.last!.index.collectionIndex, itemIndex: lowerEntries.last!.index.itemIndex, count: count - lowerEntries.count - upperEntries.count + 1, lowerCollectionId: lowerCollectionId, lowerItems: fetchLowerItems)
var additionalLowerEntries: [ItemCollectionViewEntry] = fetchLowerEntries(namespaces: namespaces, collectionId: lowerEntries.last!.index.collectionId, collectionIndex: lowerEntries.last!.index.collectionIndex, itemIndex: lowerEntries.last!.index.itemIndex, count: count - lowerEntries.count - upperEntries.count + 1, lowerCollectionId: lowerCollectionId, lowerItems: fetchLowerItems)
if additionalLowerEntries.count >= count - lowerEntries.count + upperEntries.count + 1 {
lower = additionalLowerEntries.last
@ -172,7 +162,7 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
lowerEntries.append(contentsOf: additionalLowerEntries)
}
var entries: [RawItemCollectionViewEntry] = []
var entries: [ItemCollectionViewEntry] = []
entries.append(contentsOf: lowerEntries.reversed())
entries.append(contentsOf: upperEntries)
return (entries: entries, lower: lower, upper: upper)

View File

@ -607,14 +607,14 @@ private final class DemoSheetContent: CombinedComponent {
if let items = items {
for item in items {
if let mediaItem = item.contents.get(RecentMediaItem.self) {
result.append(mediaItem.media)
result.append(mediaItem.media._parse())
}
}
}
return (reactions.reactions.filter({ $0.isPremium }).map { reaction -> AvailableReactions.Reaction in
var aroundAnimation = reaction.aroundAnimation
if let replacementFile = reactionOverrides[reaction.value] {
aroundAnimation = replacementFile
aroundAnimation = TelegramMediaFile.Accessor(replacementFile)
}
return AvailableReactions.Reaction(
@ -622,13 +622,13 @@ private final class DemoSheetContent: CombinedComponent {
isPremium: reaction.isPremium,
value: reaction.value,
title: reaction.title,
staticIcon: reaction.staticIcon,
appearAnimation: reaction.appearAnimation,
selectAnimation: reaction.selectAnimation,
activateAnimation: reaction.activateAnimation,
effectAnimation: reaction.effectAnimation,
aroundAnimation: aroundAnimation,
centerAnimation: reaction.centerAnimation
staticIcon: reaction.staticIcon._parse(),
appearAnimation: reaction.appearAnimation._parse(),
selectAnimation: reaction.selectAnimation._parse(),
activateAnimation: reaction.activateAnimation._parse(),
effectAnimation: reaction.effectAnimation._parse(),
aroundAnimation: aroundAnimation?._parse(),
centerAnimation: reaction.centerAnimation?._parse()
)
}, result.map { file -> TelegramMediaFile in
for attribute in file.attributes {

View File

@ -163,7 +163,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
if let view = views.views[stickersKey] as? OrderedItemListView {
for item in view.items {
if let mediaItem = item.contents.get(RecentMediaItem.self) {
let file = mediaItem.media
let file = mediaItem.media._parse()
strongSelf.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
if let effect = file.videoThumbnails.first {
strongSelf.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: effect.resource).start())

View File

@ -1577,7 +1577,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
if let view = views.views[stickersKey] as? OrderedItemListView {
for item in view.items {
if let mediaItem = item.contents.get(RecentMediaItem.self) {
let file = mediaItem.media
let file = mediaItem.media._parse()
strongSelf.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
if let effect = file.videoThumbnails.first {
strongSelf.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: effect.resource).start())

View File

@ -135,7 +135,7 @@ public class PremiumLimitsListScreen: ViewController {
}
}
var result: [TelegramMediaFile] = []
var result: [TelegramMediaFile.Accessor] = []
if let items = items {
for item in items {
if let mediaItem = item.contents.get(RecentMediaItem.self) {
@ -144,26 +144,22 @@ public class PremiumLimitsListScreen: ViewController {
}
}
return (result.map { file -> TelegramMediaFile in
for attribute in file.attributes {
switch attribute {
case let .Sticker(displayText, _, _):
if let replacementFile = stickerOverrides[.builtin(displayText)], let dimensions = replacementFile.dimensions {
let _ = dimensions
return TelegramMediaFile(
fileId: file.fileId,
partialReference: file.partialReference,
resource: file.resource,
previewRepresentations: file.previewRepresentations,
videoThumbnails: [TelegramMediaFile.VideoThumbnail(dimensions: dimensions, resource: replacementFile.resource)],
immediateThumbnailData: file.immediateThumbnailData,
mimeType: file.mimeType,
size: file.size,
attributes: file.attributes,
alternativeRepresentations: file.alternativeRepresentations
)
}
default:
break
let file = file._parse()
if let displayText = TelegramMediaFile.Accessor(file).stickerDisplayText {
if let replacementFile = stickerOverrides[.builtin(displayText)], let dimensions = replacementFile.dimensions {
let _ = dimensions
return TelegramMediaFile(
fileId: file.fileId,
partialReference: file.partialReference,
resource: file.resource,
previewRepresentations: file.previewRepresentations,
videoThumbnails: [TelegramMediaFile.VideoThumbnail(dimensions: dimensions, resource: replacementFile.resource)],
immediateThumbnailData: file.immediateThumbnailData,
mimeType: file.mimeType,
size: file.size,
attributes: file.attributes,
alternativeRepresentations: file.alternativeRepresentations
)
}
}
return file

View File

@ -36,22 +36,22 @@ public final class ReactionItem {
}
public let reaction: ReactionItem.Reaction
public let appearAnimation: TelegramMediaFile
public let stillAnimation: TelegramMediaFile
public let listAnimation: TelegramMediaFile
public let largeListAnimation: TelegramMediaFile
public let applicationAnimation: TelegramMediaFile?
public let largeApplicationAnimation: TelegramMediaFile?
public let appearAnimation: TelegramMediaFile.Accessor
public let stillAnimation: TelegramMediaFile.Accessor
public let listAnimation: TelegramMediaFile.Accessor
public let largeListAnimation: TelegramMediaFile.Accessor
public let applicationAnimation: TelegramMediaFile.Accessor?
public let largeApplicationAnimation: TelegramMediaFile.Accessor?
public let isCustom: Bool
public init(
reaction: ReactionItem.Reaction,
appearAnimation: TelegramMediaFile,
stillAnimation: TelegramMediaFile,
listAnimation: TelegramMediaFile,
largeListAnimation: TelegramMediaFile,
applicationAnimation: TelegramMediaFile?,
largeApplicationAnimation: TelegramMediaFile?,
appearAnimation: TelegramMediaFile.Accessor,
stillAnimation: TelegramMediaFile.Accessor,
listAnimation: TelegramMediaFile.Accessor,
largeListAnimation: TelegramMediaFile.Accessor,
applicationAnimation: TelegramMediaFile.Accessor?,
largeApplicationAnimation: TelegramMediaFile.Accessor?,
isCustom: Bool
) {
self.reaction = reaction
@ -69,7 +69,7 @@ public final class ReactionItem {
case let .builtin(value):
return .builtin(value)
case let .custom(fileId):
return .custom(fileId: fileId, file: self.listAnimation)
return .custom(fileId: fileId, file: self.listAnimation._parse())
case .stars:
return .stars
}
@ -455,21 +455,18 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
public static func randomGenericReactionEffect(context: AccountContext) -> Signal<String?, NoError> {
return context.engine.stickers.loadedStickerPack(reference: .emojiGenericAnimations, forceActualized: false)
|> map { result -> [TelegramMediaFile]? in
|> map { result -> TelegramMediaFile? in
switch result {
case let .result(_, items, _):
return items.map(\.file)
return items.randomElement()?.file._parse()
default:
return nil
}
}
|> filter { $0 != nil }
|> take(1)
|> mapToSignal { items -> Signal<String?, NoError> in
guard let items = items else {
return .single(nil)
}
guard let file = items.randomElement() else {
|> mapToSignal { file -> Signal<String?, NoError> in
guard let file else {
return .single(nil)
}
return Signal { subscriber in
@ -643,14 +640,9 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
let filterList: [String] = ["😖", "😫", "🫠", "😨", ""]
for featuredEmojiPack in view.items.lazy.map({ $0.contents.get(FeaturedStickerPackItem.self)! }) {
for item in featuredEmojiPack.topItems {
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if filterList.contains(alt) {
filteredFiles.append(item.file)
}
default:
break
if let alt = item.file.customEmojiAlt {
if filterList.contains(alt) {
filteredFiles.append(item.file._parse())
}
}
}
@ -1687,9 +1679,9 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
)
if case .locked = item.icon {
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation)
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else if strongSelf.reactionsLocked {
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation)
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else {
strongSelf.customReactionSource = (sourceView, sourceRect, sourceLayer, reactionItem)
strongSelf.reactionSelected?(updateReaction, isLongPress)
@ -1711,9 +1703,9 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
)
strongSelf.customReactionSource = (sourceView, sourceRect, sourceLayer, reactionItem)
if case .locked = item.icon {
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation)
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else if strongSelf.reactionsLocked {
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation)
strongSelf.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else {
strongSelf.reactionSelected?(reactionItem.updateMessageReaction, isLongPress)
}
@ -1925,11 +1917,11 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
}
}
let animationData = EntityKeyboardAnimationData(file: itemFile, partialReference: .none)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile), partialReference: .none)
let resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: icon,
tintMode: tintMode
@ -2037,7 +2029,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
localPacksSignal
)
|> map { view, availableReactions, hasPremium, foundPacks, foundEmoji, foundLocalPacks -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var result: [(String, TelegramMediaFile.Accessor?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
@ -2051,9 +2043,9 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, itemFile, keyword))
result.append((alt, TelegramMediaFile.Accessor(itemFile), keyword))
} else if alt == query {
result.append((alt, itemFile, alt))
result.append((alt, TelegramMediaFile.Accessor(itemFile), alt))
}
default:
break
@ -2065,18 +2057,13 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
if !item.file.isPremiumEmoji {
if let alt = item.file.customEmojiAlt {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
default:
break
}
}
}
@ -2294,11 +2281,11 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
}
}
let animationData = EntityKeyboardAnimationData(file: itemFile, partialReference: .none)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile), partialReference: .none)
let resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: icon,
tintMode: tintMode
@ -2351,11 +2338,12 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -2729,25 +2717,20 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
let additionalAnimationNode: DefaultAnimatedStickerNodeImpl?
var genericAnimationView: AnimationView?
var additionalAnimation: TelegramMediaFile?
var additionalAnimation: TelegramMediaFile.Accessor?
if self.didTriggerExpandedReaction {
additionalAnimation = itemNode.item.largeApplicationAnimation
} else {
additionalAnimation = itemNode.item.applicationAnimation
if additionalAnimation == nil && itemNode.item.isCustom {
outer: for attribute in itemNode.item.stillAnimation.attributes {
if case let .CustomEmoji(_, _, alt, _) = attribute {
if let availableReactions = self.availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == .builtin(alt) {
additionalAnimation = availableReaction.aroundAnimation
break outer
}
if let alt = itemNode.item.stillAnimation.customEmojiAlt {
if let availableReactions = self.availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == .builtin(alt) {
additionalAnimation = availableReaction.aroundAnimation
}
}
break
}
}
}
@ -2762,7 +2745,8 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
}
}
additionalAnimationNodeValue.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimation.resource), width: Int(effectFrame.width * 2.0), height: Int(effectFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimation.resource.id)))
let additionalAnimationFile = additionalAnimation._parse()
additionalAnimationNodeValue.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimationFile.resource), width: Int(effectFrame.width * 2.0), height: Int(effectFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimationFile.resource.id)))
additionalAnimationNodeValue.frame = effectFrame
additionalAnimationNodeValue.updateLayout(size: effectFrame.size)
self.addSubnode(additionalAnimationNodeValue)
@ -2799,13 +2783,14 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
for i in 1 ... 32 {
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
let itemNodeListAnimationFile = itemNode.item.listAnimation._parse()
for animationLayer in allLayers {
let baseItemLayer = InlineStickerItemLayer(
context: itemNode.context,
userLocation: .other,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
file: itemNode.item.listAnimation,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNodeListAnimationFile),
file: itemNodeListAnimationFile,
cache: animationCache,
renderer: animationRenderer,
placeholderColor: UIColor(white: 0.0, alpha: 0.0),
@ -3083,11 +3068,11 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
switch reaction {
case let .reaction(reactionItem, icon):
if case .custom = reactionItem.updateMessageReaction, let hasPremium = self.hasPremium, !hasPremium, !self.allPresetReactionsAreAvailable {
self.premiumReactionsSelected?(reactionItem.stillAnimation)
self.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else if self.reactionsLocked {
self.premiumReactionsSelected?(reactionItem.stillAnimation)
self.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else if case .locked = icon {
self.premiumReactionsSelected?(reactionItem.stillAnimation)
self.premiumReactionsSelected?(reactionItem.stillAnimation._parse())
} else {
self.reactionSelected?(reactionItem.updateMessageReaction, false)
}
@ -3274,9 +3259,9 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
for (_, itemNode) in self.visibleItemNodes {
if let itemNode = itemNode as? ReactionNode, itemNode.item.reaction == reaction {
if case .custom = itemNode.item.updateMessageReaction, let hasPremium = self.hasPremium, !hasPremium {
self.premiumReactionsSelected?(itemNode.item.stillAnimation)
self.premiumReactionsSelected?(itemNode.item.stillAnimation._parse())
} else if self.reactionsLocked {
self.premiumReactionsSelected?(itemNode.item.stillAnimation)
self.premiumReactionsSelected?(itemNode.item.stillAnimation._parse())
} else {
self.reactionSelected?(itemNode.item.updateMessageReaction, isLarge)
}
@ -3450,11 +3435,11 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
var additionalAnimationResource: MediaResource?
if isLarge && !forceSmallEffectAnimation {
additionalAnimationResource = reaction.largeApplicationAnimation?.resource
additionalAnimationResource = reaction.largeApplicationAnimation?._parse().resource
} else if case .stars = reaction.reaction.rawValue {
additionalAnimationResource = reaction.largeApplicationAnimation?.resource ?? reaction.applicationAnimation?.resource
additionalAnimationResource = reaction.largeApplicationAnimation?._parse().resource ?? reaction.applicationAnimation?._parse().resource
} else {
additionalAnimationResource = reaction.applicationAnimation?.resource
additionalAnimationResource = reaction.applicationAnimation?._parse().resource
}
if additionalAnimationResource == nil, let customEffectResource {
additionalAnimationResource = customEffectResource
@ -3540,12 +3525,13 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
for i in 1 ... 7 {
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
for animationLayer in allLayers {
let itemListAnimationFile = reaction.listAnimation._parse()
let baseItemLayer = InlineStickerItemLayer(
context: context,
userLocation: .other,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: reaction.listAnimation.fileId.id, file: reaction.listAnimation),
file: reaction.listAnimation,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: reaction.listAnimation.fileId.id, file: itemListAnimationFile),
file: itemListAnimationFile,
cache: animationCache,
renderer: animationRenderer,
placeholderColor: UIColor(white: 0.0, alpha: 0.0),
@ -3898,9 +3884,9 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
var additionalAnimation: TelegramMediaFile?
if didTriggerExpandedReaction {
additionalAnimation = item.largeApplicationAnimation
additionalAnimation = item.largeApplicationAnimation?._parse()
} else {
additionalAnimation = item.applicationAnimation
additionalAnimation = item.applicationAnimation?._parse()
}
if let additionalAnimation = additionalAnimation {

View File

@ -238,11 +238,11 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
strongSelf.animateInAnimationNode = nil
}
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.appearAnimation.resource)).start()
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.stillAnimation.resource)).start()
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.listAnimation.resource)).start()
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.appearAnimation._parse().resource)).start()
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.stillAnimation._parse().resource)).start()
self.fetchStickerDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: item.listAnimation._parse().resource)).start()
if let applicationAnimation = item.applicationAnimation {
self.fetchFullAnimationDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: applicationAnimation.resource)).start()
self.fetchFullAnimationDisposable = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .standalone(resource: applicationAnimation._parse().resource)).start()
}
if self.isLocked {
@ -357,12 +357,12 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
}
if largeExpanded {
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation.resource, isVideo: self.item.largeListAnimation.isVideoSticker || self.item.largeListAnimation.isVideoEmoji || self.item.largeListAnimation.isStaticSticker || self.item.largeListAnimation.isStaticEmoji)
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation._parse().resource, isVideo: self.item.largeListAnimation.isVideoSticker || self.item.largeListAnimation.isVideoEmoji || self.item.largeListAnimation.isStaticSticker || self.item.largeListAnimation.isStaticEmoji)
animationNode.setup(source: source, width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation.resource.id)))
animationNode.setup(source: source, width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation._parse().resource.id)))
} else {
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.item.listAnimation.resource, isVideo: self.item.listAnimation.isVideoSticker || self.item.listAnimation.isVideoEmoji || self.item.listAnimation.isVideoSticker || self.item.listAnimation.isStaticSticker || self.item.listAnimation.isStaticEmoji)
animationNode.setup(source: source, width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.listAnimation.resource.id)))
let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.item.listAnimation._parse().resource, isVideo: self.item.listAnimation.isVideoSticker || self.item.listAnimation.isVideoEmoji || self.item.listAnimation.isVideoSticker || self.item.listAnimation.isStaticSticker || self.item.listAnimation.isStaticEmoji)
animationNode.setup(source: source, width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.listAnimation._parse().resource.id)))
}
animationNode.frame = expandedAnimationFrame
animationNode.updateLayout(size: expandedAnimationFrame.size)
@ -446,7 +446,7 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
self.stillAnimationNode = stillAnimationNode
self.addSubnode(stillAnimationNode)
stillAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation.resource, isVideo: self.item.stillAnimation.isVideoEmoji || self.item.stillAnimation.isVideoSticker || self.item.stillAnimation.isStaticSticker || self.item.stillAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: self.loopIdle ? .loop : .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation.resource.id)))
stillAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation._parse().resource, isVideo: self.item.stillAnimation.isVideoEmoji || self.item.stillAnimation.isVideoSticker || self.item.stillAnimation.isStaticSticker || self.item.stillAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: self.loopIdle ? .loop : .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation._parse().resource.id)))
stillAnimationNode.position = animationFrame.center
stillAnimationNode.bounds = CGRect(origin: CGPoint(), size: animationFrame.size)
stillAnimationNode.updateLayout(size: animationFrame.size)
@ -504,9 +504,9 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
let staticFile: TelegramMediaFile
if !self.hasAppearAnimation {
staticFile = self.item.largeListAnimation
staticFile = self.item.largeListAnimation._parse()
} else {
staticFile = self.item.stillAnimation
staticFile = self.item.stillAnimation._parse()
}
if self.staticAnimationPlaceholderView == nil, let immediateThumbnailData = staticFile.immediateThumbnailData {
@ -531,9 +531,9 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
self.staticAnimationNode.automaticallyLoadFirstFrame = true
if !self.hasAppearAnimation {
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation.resource, isVideo: self.item.largeListAnimation.isVideoEmoji || self.item.largeListAnimation.isVideoSticker || self.item.largeListAnimation.isStaticSticker || self.item.largeListAnimation.isStaticEmoji), width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation.resource.id)))
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation._parse().resource, isVideo: self.item.largeListAnimation.isVideoEmoji || self.item.largeListAnimation.isVideoSticker || self.item.largeListAnimation.isStaticSticker || self.item.largeListAnimation.isStaticEmoji), width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation._parse().resource.id)))
} else {
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation.resource, isVideo: self.item.stillAnimation.isVideoEmoji || self.item.stillAnimation.isVideoSticker || self.item.stillAnimation.isStaticSticker || self.item.stillAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation.resource.id)))
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation._parse().resource, isVideo: self.item.stillAnimation.isVideoEmoji || self.item.stillAnimation.isVideoSticker || self.item.stillAnimation.isStaticSticker || self.item.stillAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation._parse().resource.id)))
}
self.staticAnimationNode.position = animationFrame.center
self.staticAnimationNode.bounds = CGRect(origin: CGPoint(), size: animationFrame.size)
@ -546,7 +546,7 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
}
if let animateInAnimationNode = self.animateInAnimationNode {
animateInAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.appearAnimation.resource, isVideo: self.item.appearAnimation.isVideoEmoji || self.item.appearAnimation.isVideoSticker || self.item.appearAnimation.isStaticSticker || self.item.appearAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.appearAnimation.resource.id)))
animateInAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.appearAnimation._parse().resource, isVideo: self.item.appearAnimation.isVideoEmoji || self.item.appearAnimation.isVideoSticker || self.item.appearAnimation.isStaticSticker || self.item.appearAnimation.isStaticEmoji), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.appearAnimation._parse().resource.id)))
animateInAnimationNode.position = animationFrame.center
animateInAnimationNode.bounds = CGRect(origin: CGPoint(), size: animationFrame.size)
animateInAnimationNode.updateLayout(size: animationFrame.size)

View File

@ -505,7 +505,7 @@ class ThemeGridThemeItemNode: ListViewItemNode, ItemListItemNode {
for theme in item.themes {
let selected = item.currentTheme.index == theme.index
let iconItem = ThemeCarouselThemeIconItem(context: item.context, emojiFile: theme.emoticon.flatMap { item.animatedEmojiStickers[$0]?.first?.file }, themeReference: theme, nightMode: item.nightMode, channelMode: false, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil, action: { theme in
let iconItem = ThemeCarouselThemeIconItem(context: item.context, emojiFile: theme.emoticon.flatMap { item.animatedEmojiStickers[$0]?.first?.file._parse() }, themeReference: theme, nightMode: item.nightMode, channelMode: false, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil, action: { theme in
if let theme {
item.updatedTheme(theme)
}

View File

@ -200,7 +200,7 @@ final class StickerPackEmojisItemNode: GridItemNode {
itemId: .animation(.file(file.fileId))
)
if let itemLayer = self.visibleItemLayers[itemId] {
return (file, itemLayer)
return (file._parse(), itemLayer)
}
}
return nil
@ -209,7 +209,7 @@ final class StickerPackEmojisItemNode: GridItemNode {
@objc private func tapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
switch recognizer.state {
case .ended:
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation, let (item, _) = self.item(atPoint: location), let file = item.itemFile {
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation, let (item, _) = self.item(atPoint: location), let file = item.itemFile?._parse() {
if case .tap = gesture {
var text = "."
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?

View File

@ -218,11 +218,12 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
let topItems = items.prefix(16)
for item in topItems {
if item.file.isAnimatedSticker {
let itemFile = item.file._parse()
let signal = Signal<Bool, NoError> { subscriber in
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: itemFile).resourceReference(itemFile.resource)).start()
let data = account.postbox.mediaBox.resourceData(itemFile.resource).start()
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: itemFile, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let hasContent = next._0 != nil || next._1 != nil
subscriber.putNext(hasContent)
if hasContent {

View File

@ -222,9 +222,9 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, ASScrol
menuItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.sendSticker?(.standalone(media: item.file), animationNode.view, animationNode.bounds)
let _ = strongSelf.sendSticker?(.standalone(media: item.file._parse()), animationNode.view, animationNode.bounds)
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.sendSticker?(.standalone(media: item.file), imageNode.view, imageNode.bounds)
let _ = strongSelf.sendSticker?(.standalone(media: item.file._parse()), imageNode.view, imageNode.bounds)
}
}
f(.default)
@ -234,13 +234,13 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, ASScrol
f(.default)
if let strongSelf = self {
let _ = strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred).start(next: { result in
let _ = strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file._parse(), saved: !isStarred).start(next: { result in
})
}
})))
}
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file), isLocked: item.file.isPremiumSticker && !hasPremium, menu: menuItems, openPremiumIntro: {
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file._parse()), isLocked: item.file.isPremiumSticker && !hasPremium, menu: menuItems, openPremiumIntro: {
}))
} else {

View File

@ -310,12 +310,14 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
self.setupTimestamp = CACurrentMediaTime()
}
let stickerItemFile = stickerItem.file._parse()
if stickerItem.file.isAnimatedSticker || stickerItem.file.isVideoSticker {
let dimensions = stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
if stickerItem.file.isVideoSticker {
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItem.file, small: true, fetched: true))
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItemFile, small: true, fetched: true))
} else {
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, userLocation: .other, file: stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))))
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, userLocation: .other, file: stickerItemFile, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))))
}
if self.animationNode == nil {
@ -339,14 +341,14 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
}
}
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: context.account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: context.account, resource: stickerItemFile.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached)
self.animationNode?.visibility = visibility
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: stickerItem.file.resource).start())
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItemFile), resource: stickerItemFile.resource).start())
if stickerItem.file.isPremiumSticker, let effect = stickerItem.file.videoThumbnails.first {
self.effectFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: effect.resource).start())
if stickerItem.file.isPremiumSticker, let effect = stickerItemFile.videoThumbnails.first {
self.effectFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItemFile), resource: effect.resource).start())
}
} else {
if let animationNode = self.animationNode {
@ -354,8 +356,8 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
self.animationNode = nil
animationNode.removeFromSupernode()
}
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItem.file, small: true))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start())
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItemFile, small: true))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItemFile), resource: chatMessageStickerResource(file: stickerItemFile, small: true)).start())
}
} else {
if isEmpty {
@ -516,7 +518,7 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
if isAdd {
return
}
isPreviewing = interaction.previewedItem == .pack(item.file)
isPreviewing = interaction.previewedItem == .pack(item.file._parse())
}
if self.currentIsPreviewing != isPreviewing {
self.currentIsPreviewing = isPreviewing

View File

@ -543,9 +543,9 @@ private final class StickerPackContainer: ASDisplayNode {
menuItems.append(.action(ContextMenuActionItem(text: actionTitle, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: iconName), color: theme.contextMenu.primaryColor) }, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.sendSticker?(.standalone(media: item.file), animationNode.view, animationNode.bounds)
let _ = strongSelf.sendSticker?(.standalone(media: item.file._parse()), animationNode.view, animationNode.bounds)
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.sendSticker?(.standalone(media: item.file), imageNode.view, imageNode.bounds)
let _ = strongSelf.sendSticker?(.standalone(media: item.file._parse()), imageNode.view, imageNode.bounds)
}
}
f(.default)
@ -555,10 +555,10 @@ private final class StickerPackContainer: ASDisplayNode {
f(.default)
if let strongSelf = self {
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file._parse(), saved: !isStarred)
|> deliverOnMainQueue).start(next: { [weak self] result in
if let self, let contorller = self.controller {
contorller.present(UndoOverlayController(presentationData: self.presentationData, content: .sticker(context: context, file: item.file, loop: true, title: nil, text: !isStarred ? self.presentationData.strings.Conversation_StickerAddedToFavorites : self.presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
contorller.present(UndoOverlayController(presentationData: self.presentationData, content: .sticker(context: context, file: item.file._parse(), loop: true, title: nil, text: !isStarred ? self.presentationData.strings.Conversation_StickerAddedToFavorites : self.presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
}
})
}
@ -568,7 +568,7 @@ private final class StickerPackContainer: ASDisplayNode {
menuItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Stickers_EditSticker, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Draw"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
if let self {
self.openEditSticker(item.file)
self.openEditSticker(item.file._parse())
}
})))
if !strongSelf.isEditing {
@ -601,7 +601,7 @@ private final class StickerPackContainer: ASDisplayNode {
} else {
self.currentStickerPack = (info, updatedItems, installed)
self.reorderAndUpdateEntries()
let _ = self.context.engine.stickers.deleteStickerFromStickerSet(sticker: .stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file)).startStandalone()
let _ = self.context.engine.stickers.deleteStickerFromStickerSet(sticker: .stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file._parse())).startStandalone()
}
}
}))
@ -611,7 +611,7 @@ private final class StickerPackContainer: ASDisplayNode {
})))
}
}
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file), isLocked: item.file.isPremiumSticker && !hasPremium, menu: menuItems, openPremiumIntro: { [weak self] in
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, item: .pack(item.file._parse()), isLocked: item.file.isPremiumSticker && !hasPremium, menu: menuItems, openPremiumIntro: { [weak self] in
guard let strongSelf = self else {
return
}
@ -752,7 +752,7 @@ private final class StickerPackContainer: ASDisplayNode {
self.reorderFeedback?.tap()
if let reorderPosition = self.reorderPosition, let file = itemNode.stickerPackItem?.file {
let _ = self.context.engine.stickers.reorderSticker(sticker: .standalone(media: file), position: reorderPosition).startStandalone()
let _ = self.context.engine.stickers.reorderSticker(sticker: .standalone(media: file._parse()), position: reorderPosition).startStandalone()
if let (info, items, isInstalled) = self.currentStickerPack {
var updatedItems = items

View File

@ -133,11 +133,13 @@ final class StickerPreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
self.item = item
for case let .Sticker(text, _, _) in item.file.attributes {
let itemFile = item.file._parse()
for case let .Sticker(text, _, _) in itemFile.attributes {
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(32.0), textColor: .black)
break
}
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: item.file, small: false, onlyFullSize: false))
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: itemFile, small: false, onlyFullSize: false))
if let (layout, navigationBarHeight) = self.containerLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)

View File

@ -622,10 +622,11 @@ public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCol
if let item = items.first as? StickerPackItem {
if item.file.isAnimatedSticker {
let signal = Signal<Bool, NoError> { subscriber in
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let itemFile = item.file._parse()
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: itemFile).resourceReference(itemFile.resource)).start()
let data = account.postbox.mediaBox.resourceData(itemFile.resource).start()
let dimensions = itemFile.dimensions ?? PixelDimensions(width: 512, height: 512)
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: itemFile, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let hasContent = next._0 != nil || next._1 != nil
subscriber.putNext(hasContent)
if hasContent {
@ -641,9 +642,10 @@ public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCol
return signal
} else {
let signal = Signal<Bool, NoError> { subscriber in
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: true, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let itemFile = item.file._parse()
let data = account.postbox.mediaBox.resourceData(itemFile.resource).start()
let dimensions = itemFile.dimensions ?? PixelDimensions(width: 512, height: 512)
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: itemFile, small: true, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
let hasContent = next._0 != nil || next._1 != nil
subscriber.putNext(hasContent)
if hasContent {

View File

@ -180,7 +180,7 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP
remoteVideo: nil,
isRemoteBatteryLow: false,
isEnergySavingEnabled: !self.sharedContext.energyUsageSettings.fullTranslucency,
isConferencePossible: self.sharedContext.immediateExperimentalUISettings.conferenceCalls
isConferencePossible: true
)
self.isMicrophoneMutedDisposable = (call.isMuted

View File

@ -413,10 +413,8 @@ public final class PresentationCallImpl: PresentationCall {
if let data = context.currentAppConfiguration.with({ $0 }).data, let _ = data["ios_killswitch_disable_call_device"] {
self.sharedAudioContext = nil
} else if context.sharedContext.immediateExperimentalUISettings.conferenceCalls {
self.sharedAudioContext = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration)
} else {
self.sharedAudioContext = nil
self.sharedAudioContext = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration)
}
if let _ = self.sharedAudioContext {

View File

@ -540,10 +540,10 @@ final class MediaReferenceRevalidationContext {
}
}
func savedGifs(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> {
func savedGifs(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> {
return self.genericItem(key: .savedGifs, background: background, request: { next, error in
let loadRecentGifs: Signal<[TelegramMediaFile], NoError> = postbox.transaction { transaction -> [TelegramMediaFile] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentGifs).compactMap({ item -> TelegramMediaFile? in
let loadRecentGifs: Signal<[TelegramMediaFile.Accessor], NoError> = postbox.transaction { transaction -> [TelegramMediaFile.Accessor] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentGifs).compactMap({ item -> TelegramMediaFile.Accessor? in
if let contents = item.contents.get(RecentMediaItem.self) {
let file = contents.media
return file
@ -552,7 +552,7 @@ final class MediaReferenceRevalidationContext {
})
}
return (managedRecentGifs(postbox: postbox, network: network, forceFetch: true)
|> mapToSignal { _ -> Signal<[TelegramMediaFile], NoError> in
|> mapToSignal { _ -> Signal<[TelegramMediaFile.Accessor], NoError> in
return .complete()
}
|> then(loadRecentGifs)
@ -561,8 +561,8 @@ final class MediaReferenceRevalidationContext {
}, error: { _ in
error(.generic)
})
}) |> mapToSignal { next -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile] {
}) |> mapToSignal { next -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile.Accessor] {
return .single(next)
} else {
return .fail(.generic)
@ -570,10 +570,10 @@ final class MediaReferenceRevalidationContext {
}
}
func savedStickers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> {
func savedStickers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> {
return self.genericItem(key: .savedStickers, background: background, request: { next, error in
let loadSavedStickers: Signal<[TelegramMediaFile], NoError> = postbox.transaction { transaction -> [TelegramMediaFile] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudSavedStickers).compactMap({ item -> TelegramMediaFile? in
let loadSavedStickers: Signal<[TelegramMediaFile.Accessor], NoError> = postbox.transaction { transaction -> [TelegramMediaFile.Accessor] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudSavedStickers).compactMap({ item -> TelegramMediaFile.Accessor? in
if let contents = item.contents.get(SavedStickerItem.self) {
let file = contents.file
return file
@ -582,7 +582,7 @@ final class MediaReferenceRevalidationContext {
})
}
return (managedSavedStickers(postbox: postbox, network: network, forceFetch: true)
|> mapToSignal { _ -> Signal<[TelegramMediaFile], NoError> in
|> mapToSignal { _ -> Signal<[TelegramMediaFile.Accessor], NoError> in
return .complete()
}
|> then(loadSavedStickers)
@ -591,8 +591,8 @@ final class MediaReferenceRevalidationContext {
}, error: { _ in
error(.generic)
})
}) |> mapToSignal { next -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile] {
}) |> mapToSignal { next -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile.Accessor] {
return .single(next)
} else {
return .fail(.generic)
@ -600,10 +600,10 @@ final class MediaReferenceRevalidationContext {
}
}
func recentStickers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> {
func recentStickers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> {
return self.genericItem(key: .recentStickers, background: background, request: { next, error in
let loadRecentStickers: Signal<[TelegramMediaFile], NoError> = postbox.transaction { transaction -> [TelegramMediaFile] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentStickers).compactMap({ item -> TelegramMediaFile? in
let loadRecentStickers: Signal<[TelegramMediaFile.Accessor], NoError> = postbox.transaction { transaction -> [TelegramMediaFile.Accessor] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentStickers).compactMap({ item -> TelegramMediaFile.Accessor? in
if let contents = item.contents.get(RecentMediaItem.self) {
let file = contents.media
return file
@ -612,7 +612,7 @@ final class MediaReferenceRevalidationContext {
})
}
return (managedRecentStickers(postbox: postbox, network: network, forceFetch: true)
|> mapToSignal { _ -> Signal<[TelegramMediaFile], NoError> in
|> mapToSignal { _ -> Signal<[TelegramMediaFile.Accessor], NoError> in
return .complete()
}
|> then(loadRecentStickers)
@ -621,8 +621,8 @@ final class MediaReferenceRevalidationContext {
}, error: { _ in
error(.generic)
})
}) |> mapToSignal { next -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile] {
}) |> mapToSignal { next -> Signal<[TelegramMediaFile.Accessor], RevalidateMediaReferenceError> in
if let next = next as? [TelegramMediaFile.Accessor] {
return .single(next)
} else {
return .fail(.generic)
@ -876,10 +876,11 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
for item in result.1 {
if let item = item as? StickerPackItem {
if media.id != nil && item.file.id == media.id {
if let updatedResource = findUpdatedMediaResource(media: item.file, previousMedia: media, resource: resource) {
let itemFile = item.file._parse()
if let updatedResource = findUpdatedMediaResource(media: itemFile, previousMedia: media, resource: resource) {
return postbox.transaction { transaction -> RevalidatedMediaResource in
if let id = media.id {
var attributes = item.file.attributes
var attributes = itemFile.attributes
if !attributes.contains(where: { attribute in
if case .hintIsValidated = attribute {
return true
@ -889,7 +890,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
}) {
attributes.append(.hintIsValidated)
}
let file = item.file.withUpdatedAttributes(attributes)
let file = itemFile.withUpdatedAttributes(attributes)
updateMessageMedia(transaction: transaction, id: id, media: file)
}
return RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil)
@ -914,7 +915,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
|> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
for file in result {
if media.id != nil && file.id == media.id {
if let updatedResource = findUpdatedMediaResource(media: file, previousMedia: media, resource: resource) {
if let updatedResource = findUpdatedMediaResource(media: file._parse(), previousMedia: media, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
}
}
@ -926,7 +927,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
|> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
for file in result {
if media.id != nil && file.id == media.id {
if let updatedResource = findUpdatedMediaResource(media: file, previousMedia: media, resource: resource) {
if let updatedResource = findUpdatedMediaResource(media: file._parse(), previousMedia: media, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
}
}
@ -938,7 +939,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
|> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
for file in result {
if media.id != nil && file.id == media.id {
if let updatedResource = findUpdatedMediaResource(media: file, previousMedia: media, resource: resource) {
if let updatedResource = findUpdatedMediaResource(media: file._parse(), previousMedia: media, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
}
}
@ -1001,7 +1002,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
for item in result.1 {
if let item = item as? StickerPackItem {
if media.id != nil && item.file.id == media.id {
if let updatedResource = findUpdatedMediaResource(media: item.file, previousMedia: media, resource: resource) {
if let updatedResource = findUpdatedMediaResource(media: item.file._parse(), previousMedia: media, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
}
}

View File

@ -2,6 +2,8 @@ import Foundation
import TelegramApi
import Postbox
import SwiftSignalKit
import FlatBuffers
import FlatSerialization
private func generateStarsReactionFile(kind: Int, isAnimatedSticker: Bool) -> TelegramMediaFile {
let baseId: Int64 = 52343278047832950 + 10
@ -27,7 +29,7 @@ private func generateStarsReactionFile(kind: Int, isAnimatedSticker: Bool) -> Te
)
}
private func generateStarsReaction() -> AvailableReactions.Reaction {
private let sharedStarsReaction: AvailableReactions.Reaction = {
return AvailableReactions.Reaction(
isEnabled: false,
isPremium: false,
@ -41,7 +43,7 @@ private func generateStarsReaction() -> AvailableReactions.Reaction {
aroundAnimation: generateStarsReactionFile(kind: 5, isAnimatedSticker: true),
centerAnimation: generateStarsReactionFile(kind: 6, isAnimatedSticker: true)
)
}
}()
public final class AvailableReactions: Equatable, Codable {
public final class Reaction: Equatable, Codable {
@ -51,12 +53,19 @@ public final class AvailableReactions: Equatable, Codable {
case value
case title
case staticIcon
case staticIconData
case appearAnimation
case appearAnimationData
case selectAnimation
case selectAnimationData
case activateAnimation
case activateAnimationData
case effectAnimation
case effectAnimationData
case aroundAnimation
case aroundAnimationData
case centerAnimation
case centerAnimationData
case isStars
}
@ -64,13 +73,13 @@ public final class AvailableReactions: Equatable, Codable {
public let isPremium: Bool
public let value: MessageReaction.Reaction
public let title: String
public let staticIcon: TelegramMediaFile
public let appearAnimation: TelegramMediaFile
public let selectAnimation: TelegramMediaFile
public let activateAnimation: TelegramMediaFile
public let effectAnimation: TelegramMediaFile
public let aroundAnimation: TelegramMediaFile?
public let centerAnimation: TelegramMediaFile?
public let staticIcon: TelegramMediaFile.Accessor
public let appearAnimation: TelegramMediaFile.Accessor
public let selectAnimation: TelegramMediaFile.Accessor
public let activateAnimation: TelegramMediaFile.Accessor
public let effectAnimation: TelegramMediaFile.Accessor
public let aroundAnimation: TelegramMediaFile.Accessor?
public let centerAnimation: TelegramMediaFile.Accessor?
public init(
isEnabled: Bool,
@ -89,13 +98,13 @@ public final class AvailableReactions: Equatable, Codable {
self.isPremium = isPremium
self.value = value
self.title = title
self.staticIcon = staticIcon
self.appearAnimation = appearAnimation
self.selectAnimation = selectAnimation
self.activateAnimation = activateAnimation
self.effectAnimation = effectAnimation
self.aroundAnimation = aroundAnimation
self.centerAnimation = centerAnimation
self.staticIcon = TelegramMediaFile.Accessor(staticIcon)
self.appearAnimation = TelegramMediaFile.Accessor(appearAnimation)
self.selectAnimation = TelegramMediaFile.Accessor(selectAnimation)
self.activateAnimation = TelegramMediaFile.Accessor(activateAnimation)
self.effectAnimation = TelegramMediaFile.Accessor(effectAnimation)
self.aroundAnimation = aroundAnimation.flatMap(TelegramMediaFile.Accessor.init)
self.centerAnimation = centerAnimation.flatMap(TelegramMediaFile.Accessor.init)
}
public static func ==(lhs: Reaction, rhs: Reaction) -> Bool {
@ -149,29 +158,60 @@ public final class AvailableReactions: Equatable, Codable {
}
self.title = try container.decode(String.self, forKey: .title)
let staticIconData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .staticIcon)
self.staticIcon = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: staticIconData.data)))
if let staticIconData = try container.decodeIfPresent(Data.self, forKey: .staticIconData) {
var byteBuffer = ByteBuffer(data: staticIconData)
self.staticIcon = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, staticIconData)
} else {
let staticIconData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .staticIcon)
self.staticIcon = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: staticIconData.data))))
}
let appearAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .appearAnimation)
self.appearAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: appearAnimationData.data)))
if let appearAnimationData = try container.decodeIfPresent(Data.self, forKey: .appearAnimationData) {
var byteBuffer = ByteBuffer(data: appearAnimationData)
self.appearAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, appearAnimationData)
} else {
let appearAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .appearAnimation)
self.appearAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: appearAnimationData.data))))
}
let selectAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .selectAnimation)
self.selectAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: selectAnimationData.data)))
if let selectAnimationData = try container.decodeIfPresent(Data.self, forKey: .selectAnimationData) {
var byteBuffer = ByteBuffer(data: selectAnimationData)
self.selectAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, selectAnimationData)
} else {
let selectAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .selectAnimation)
self.selectAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: selectAnimationData.data))))
}
let activateAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .activateAnimation)
self.activateAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: activateAnimationData.data)))
if let activateAnimationData = try container.decodeIfPresent(Data.self, forKey: .activateAnimationData) {
var byteBuffer = ByteBuffer(data: activateAnimationData)
self.activateAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, activateAnimationData)
} else {
let activateAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .activateAnimation)
self.activateAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: activateAnimationData.data))))
}
let effectAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .effectAnimation)
self.effectAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: effectAnimationData.data)))
if let effectAnimationData = try container.decodeIfPresent(Data.self, forKey: .effectAnimationData) {
var byteBuffer = ByteBuffer(data: effectAnimationData)
self.effectAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, effectAnimationData)
} else {
let effectAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .effectAnimation)
self.effectAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: effectAnimationData.data))))
}
if let aroundAnimationData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: .aroundAnimation) {
self.aroundAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: aroundAnimationData.data)))
if let aroundAnimationData = try container.decodeIfPresent(Data.self, forKey: .aroundAnimationData) {
var byteBuffer = ByteBuffer(data: aroundAnimationData)
self.aroundAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, aroundAnimationData)
} else if let aroundAnimationData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: .aroundAnimation) {
self.aroundAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: aroundAnimationData.data))))
} else {
self.aroundAnimation = nil
}
if let centerAnimationData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: .centerAnimation) {
self.centerAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: centerAnimationData.data)))
if let centerAnimationData = try container.decodeIfPresent(Data.self, forKey: .centerAnimationData) {
var byteBuffer = ByteBuffer(data: centerAnimationData)
self.centerAnimation = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, centerAnimationData)
} else if let centerAnimationData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: .centerAnimation) {
self.centerAnimation = TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: centerAnimationData.data))))
} else {
self.centerAnimation = nil
}
@ -193,16 +233,31 @@ public final class AvailableReactions: Equatable, Codable {
}
try container.encode(self.title, forKey: .title)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.staticIcon), forKey: .staticIcon)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.appearAnimation), forKey: .appearAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.selectAnimation), forKey: .selectAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.activateAnimation), forKey: .activateAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.effectAnimation), forKey: .effectAnimation)
let encodeFileItem: (TelegramMediaFile.Accessor, CodingKeys) throws -> Void = { file, key in
if let serializedFile = file._wrappedData {
try container.encode(serializedFile, forKey: key)
} else if let file = file._wrappedFile {
var builder = FlatBufferBuilder(initialSize: 1024)
let value = file.encodeToFlatBuffers(builder: &builder)
builder.finish(offset: value)
let serializedFile = builder.data
try container.encode(serializedFile, forKey: key)
} else {
preconditionFailure()
}
}
try encodeFileItem(self.staticIcon, .staticIconData)
try encodeFileItem(self.appearAnimation, .appearAnimationData)
try encodeFileItem(self.selectAnimation, .selectAnimationData)
try encodeFileItem(self.activateAnimation, .activateAnimationData)
try encodeFileItem(self.effectAnimation, .effectAnimationData)
if let aroundAnimation = self.aroundAnimation {
try container.encode(PostboxEncoder().encodeObjectToRawData(aroundAnimation), forKey: .aroundAnimation)
try encodeFileItem(aroundAnimation, .aroundAnimationData)
}
if let centerAnimation = self.centerAnimation {
try container.encode(PostboxEncoder().encodeObjectToRawData(centerAnimation), forKey: .centerAnimation)
try encodeFileItem(centerAnimation, .centerAnimationData)
}
}
}
@ -223,7 +278,7 @@ public final class AvailableReactions: Equatable, Codable {
var reactions = reactions
reactions.removeAll(where: { if case .stars = $0.value { return true } else { return false } })
reactions.append(generateStarsReaction())
reactions.append(sharedStarsReaction)
self.reactions = reactions
}
@ -244,7 +299,7 @@ public final class AvailableReactions: Equatable, Codable {
var reactions = try container.decode([Reaction].self, forKey: .reactions)
reactions.removeAll(where: { if case .stars = $0.value { return true } else { return false } })
reactions.append(generateStarsReaction())
reactions.append(sharedStarsReaction)
self.reactions = reactions
}
@ -324,27 +379,27 @@ func _internal_setCachedAvailableReactions(transaction: Transaction, availableRe
}
func managedSynchronizeAvailableReactions(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
let starsReaction = generateStarsReaction()
let mapping: [String: KeyPath<AvailableReactions.Reaction, TelegramMediaFile>] = [
let starsReaction = sharedStarsReaction
let mapping: [String: KeyPath<AvailableReactions.Reaction, TelegramMediaFile.Accessor>] = [
"star_reaction_activate.tgs": \.activateAnimation,
"star_reaction_appear.tgs": \.appearAnimation,
"star_reaction_effect.tgs": \.effectAnimation,
"star_reaction_select.tgs": \.selectAnimation,
"star_reaction_static_icon.webp": \.staticIcon
]
let optionalMapping: [String: KeyPath<AvailableReactions.Reaction, TelegramMediaFile?>] = [
let optionalMapping: [String: KeyPath<AvailableReactions.Reaction, TelegramMediaFile.Accessor?>] = [
"star_reaction_center.tgs": \.centerAnimation,
"star_reaction_effect.tgs": \.aroundAnimation
]
for (key, path) in mapping {
if let filePath = Bundle.main.path(forResource: key, ofType: nil), let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) {
postbox.mediaBox.storeResourceData(starsReaction[keyPath: path].resource.id, data: data)
postbox.mediaBox.storeResourceData(starsReaction[keyPath: path]._parse().resource.id, data: data)
}
}
for (key, path) in optionalMapping {
if let filePath = Bundle.main.path(forResource: key, ofType: nil), let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) {
if let file = starsReaction[keyPath: path] {
postbox.mediaBox.storeResourceData(file.resource.id, data: data)
postbox.mediaBox.storeResourceData(file._parse().resource.id, data: data)
}
}
}
@ -380,16 +435,16 @@ func managedSynchronizeAvailableReactions(postbox: Postbox, network: Network) ->
var resources: [MediaResource] = []
for reaction in availableReactions.reactions {
resources.append(reaction.staticIcon.resource)
resources.append(reaction.appearAnimation.resource)
resources.append(reaction.selectAnimation.resource)
resources.append(reaction.activateAnimation.resource)
resources.append(reaction.effectAnimation.resource)
resources.append(reaction.staticIcon._parse().resource)
resources.append(reaction.appearAnimation._parse().resource)
resources.append(reaction.selectAnimation._parse().resource)
resources.append(reaction.activateAnimation._parse().resource)
resources.append(reaction.effectAnimation._parse().resource)
if let centerAnimation = reaction.centerAnimation {
resources.append(centerAnimation.resource)
resources.append(centerAnimation._parse().resource)
}
if let aroundAnimation = reaction.aroundAnimation {
resources.append(aroundAnimation.resource)
resources.append(aroundAnimation._parse().resource)
}
}

View File

@ -495,7 +495,7 @@ func managedRecentReactions(postbox: Postbox, network: Network) -> Signal<Void,
guard let file = files[fileId] else {
continue
}
item = RecentReactionItem(.custom(file))
item = RecentReactionItem(.custom(TelegramMediaFile.Accessor(file)))
case .stars:
item = RecentReactionItem(.stars)
}
@ -552,7 +552,7 @@ func managedTopReactions(postbox: Postbox, network: Network) -> Signal<Void, NoE
guard let file = files[fileId] else {
continue
}
item = RecentReactionItem(.custom(file))
item = RecentReactionItem(.custom(TelegramMediaFile.Accessor(file)))
case .stars:
item = RecentReactionItem(.stars)
}
@ -609,7 +609,7 @@ func managedDefaultTagReactions(postbox: Postbox, network: Network) -> Signal<Vo
guard let file = files[fileId] else {
continue
}
item = RecentReactionItem(.custom(file))
item = RecentReactionItem(.custom(TelegramMediaFile.Accessor(file)))
case .stars:
item = RecentReactionItem(.stars)
}

View File

@ -569,7 +569,7 @@ private func continueSynchronizeInstalledStickerPacks(transaction: Transaction,
let items = transaction.getItemCollectionItems(collectionId: id)
for item in items {
if let stickerItem = item as? StickerPackItem, stickerItem.file.isPremiumSticker,
let entry = CodableEntry(RecentMediaItem(stickerItem.file)) {
let entry = CodableEntry(RecentMediaItem(stickerItem.file._parse())) {
premiumStickers.append(OrderedItemListEntry(id: RecentMediaItemId(stickerItem.file.fileId).rawValue, contents: entry))
}
}
@ -690,7 +690,7 @@ private func continueSynchronizeInstalledStickerPacks(transaction: Transaction,
let items = transaction.getItemCollectionItems(collectionId: id)
for item in items {
if let stickerItem = item as? StickerPackItem, stickerItem.file.isPremiumSticker,
let entry = CodableEntry(RecentMediaItem(stickerItem.file)) {
let entry = CodableEntry(RecentMediaItem(stickerItem.file._parse())) {
premiumStickers.append(OrderedItemListEntry(id: RecentMediaItemId(stickerItem.file.fileId).rawValue, contents: entry))
}
}

View File

@ -135,7 +135,7 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
recentReactionItem = RecentReactionItem(.builtin(value))
case let .custom(fileId, file):
if let file = file ?? (transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile) {
recentReactionItem = RecentReactionItem(.custom(file))
recentReactionItem = RecentReactionItem(.custom(TelegramMediaFile.Accessor(file)))
} else {
continue
}

View File

@ -45,7 +45,7 @@ public func removeSavedGif(postbox: Postbox, mediaId: MediaId) -> Signal<Void, N
return postbox.transaction { transaction -> Void in
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(RecentMediaItem.self) {
let file = item.media
if let resource = file.resource as? CloudDocumentMediaResource {
if let resource = file._parse().resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, itemId: entry.id)
addSynchronizeSavedGifsOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
}

View File

@ -54,7 +54,7 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe
if stickerItem.file.fileId == file.fileId {
let stringRepresentations = stickerItem.getStringRepresentationsOfIndexKeys()
found = true
addSavedSticker(transaction: transaction, file: stickerItem.file, stringRepresentations: stringRepresentations)
addSavedSticker(transaction: transaction, file: stickerItem.file._parse(), stringRepresentations: stringRepresentations)
break inner
}
}
@ -124,7 +124,7 @@ public func addSavedSticker(transaction: Transaction, file: TelegramMediaFile, s
public func removeSavedSticker(transaction: Transaction, mediaId: MediaId) {
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(SavedStickerItem.self) {
if let resource = item.file.resource as? CloudDocumentMediaResource {
if let resource = item.file._parse().resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: entry.id)
addSynchronizeSavedStickersOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
}
@ -134,7 +134,7 @@ public func removeSavedSticker(transaction: Transaction, mediaId: MediaId) {
public func removeSavedSticker(postbox: Postbox, mediaId: MediaId) -> Signal<Void, NoError> {
return postbox.transaction { transaction in
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(SavedStickerItem.self) {
if let resource = item.file.resource as? CloudDocumentMediaResource {
if let resource = item.file._parse().resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: entry.id)
addSynchronizeSavedStickersOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
}

View File

@ -961,7 +961,7 @@ public final class WallpaperDataResource: TelegramMediaResource {
public func TelegramMediaResource_parse(flatBuffersData data: Data) throws -> TelegramMediaResource {
var byteBuffer = ByteBuffer(data: data)
let flatBuffersObject: TelegramCore_TelegramMediaResource = try getCheckedRoot(byteBuffer: &byteBuffer)
let flatBuffersObject: TelegramCore_TelegramMediaResource = getRoot(byteBuffer: &byteBuffer)
return try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject)
}

View File

@ -1,5 +1,7 @@
import Foundation
import Postbox
import FlatBuffers
import FlatSerialization
public struct RecentMediaItemId {
public let rawValue: MemoryBuffer
@ -26,27 +28,47 @@ public struct RecentMediaItemId {
}
public final class RecentMediaItem: Codable, Equatable {
public let media: TelegramMediaFile
public let media: TelegramMediaFile.Accessor
private let serializedFile: Data?
public init(_ media: TelegramMediaFile) {
self.media = media
self.media = TelegramMediaFile.Accessor(media)
self.serializedFile = nil
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let mediaData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m")
self.media = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data)))
if let serializedFileData = try container.decodeIfPresent(Data.self, forKey: "md") {
self.serializedFile = serializedFileData
var byteBuffer = ByteBuffer(data: serializedFileData)
self.media = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, serializedFileData)
} else {
let mediaData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m")
let media = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data)))
self.media = TelegramMediaFile.Accessor(media)
self.serializedFile = nil
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.media), forKey: "m")
if let serializedFile = self.serializedFile {
try container.encode(serializedFile, forKey: "md")
} else if let file = self.media._wrappedFile {
var builder = FlatBufferBuilder(initialSize: 1024)
let value = file.encodeToFlatBuffers(builder: &builder)
builder.finish(offset: value)
let serializedFile = builder.data
try container.encode(serializedFile, forKey: "md")
} else {
preconditionFailure()
}
}
public static func ==(lhs: RecentMediaItem, rhs: RecentMediaItem) -> Bool {
return lhs.media.isEqual(to: rhs.media)
return lhs.media == rhs.media
}
}
@ -233,7 +255,7 @@ public struct RecentReactionItemId {
public final class RecentReactionItem: Codable, Equatable {
public enum Content: Equatable {
case custom(TelegramMediaFile)
case custom(TelegramMediaFile.Accessor)
case builtin(String)
case stars
}
@ -257,9 +279,13 @@ public final class RecentReactionItem: Codable, Equatable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
if let mediaData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m") {
self.content = .custom(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data))))
if let mediaData = try container.decodeIfPresent(Data.self, forKey: "md") {
var byteBuffer = ByteBuffer(data: mediaData)
let file = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, mediaData)
self.content = .custom(file)
} else if let mediaData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m") {
self.content = .custom(TelegramMediaFile.Accessor(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data)))))
} else if let _ = try container.decodeIfPresent(Int64.self, forKey: "star") {
self.content = .stars
} else {
@ -272,7 +298,17 @@ public final class RecentReactionItem: Codable, Equatable {
switch self.content {
case let .custom(file):
try container.encode(PostboxEncoder().encodeObjectToRawData(file), forKey: "m")
if let serializedFile = file._wrappedData {
try container.encode(serializedFile, forKey: "md")
} else if let file = file._wrappedFile {
var builder = FlatBufferBuilder(initialSize: 1024)
let value = file.encodeToFlatBuffers(builder: &builder)
builder.finish(offset: value)
let serializedFile = builder.data
try container.encode(serializedFile, forKey: "md")
} else {
preconditionFailure()
}
case let .builtin(string):
try container.encode(string, forKey: "s")
case .stars:

View File

@ -1,30 +1,50 @@
import Foundation
import Postbox
import FlatBuffers
import FlatSerialization
public final class SavedStickerItem: Codable, Equatable {
public let file: TelegramMediaFile
public let file: TelegramMediaFile.Accessor
public let stringRepresentations: [String]
public init(file: TelegramMediaFile, stringRepresentations: [String]) {
self.file = file
self.file = TelegramMediaFile.Accessor(file)
self.stringRepresentations = stringRepresentations
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: (try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "f")).data)))
if let serializedFileData = try container.decodeIfPresent(Data.self, forKey: "fd") {
var byteBuffer = ByteBuffer(data: serializedFileData)
self.file = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, serializedFileData)
} else {
let file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: (try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "f")).data)))
self.file = TelegramMediaFile.Accessor(file)
}
self.stringRepresentations = try container.decode([String].self, forKey: "sr")
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.file), forKey: "f")
if let serializedFile = self.file._wrappedData {
try container.encode(serializedFile, forKey: "fd")
} else if let file = self.file._wrappedFile {
var builder = FlatBufferBuilder(initialSize: 1024)
let value = file.encodeToFlatBuffers(builder: &builder)
builder.finish(offset: value)
let serializedFile = builder.data
try container.encode(serializedFile, forKey: "fd")
} else {
preconditionFailure()
}
try container.encode(self.stringRepresentations, forKey: "sr")
}
public static func ==(lhs: SavedStickerItem, rhs: SavedStickerItem) -> Bool {
return lhs.file.isEqual(to: rhs.file) && lhs.stringRepresentations == rhs.stringRepresentations
return lhs.file == rhs.file && lhs.stringRepresentations == rhs.stringRepresentations
}
}

View File

@ -5,34 +5,67 @@ import FlatSerialization
public final class StickerPackItem: ItemCollectionItem, Equatable {
public let index: ItemCollectionItemIndex
public let file: TelegramMediaFile
public let serializedFile: Data
public let file: TelegramMediaFile.Accessor
public let indexKeys: [MemoryBuffer]
public init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
self.index = index
self.file = file
self.serializedFile = file.encodeToFlatBuffersData()
self.file = TelegramMediaFile.Accessor(file)
self.indexKeys = indexKeys
}
public init?(index: ItemCollectionItemIndex, serializedFile: Data, indexKeys: [MemoryBuffer]) {
self.index = index
var byteBuffer = ByteBuffer(data: serializedFile)
let accessor = getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile
self.file = TelegramMediaFile.Accessor(accessor, serializedFile)
self.indexKeys = indexKeys
}
public init(decoder: PostboxDecoder) {
self.index = ItemCollectionItemIndex(index: decoder.decodeInt32ForKey("i.n", orElse: 0), id: decoder.decodeInt64ForKey("i.i", orElse: 0))
self.file = decoder.decodeObjectForKey("f") as! TelegramMediaFile
self.serializedFile = decoder.decodeDataForKey("fd") ?? self.file.encodeToFlatBuffersData()
if let serializedFileData = decoder.decodeDataForKey("fd") {
var byteBuffer = ByteBuffer(data: serializedFileData)
self.file = TelegramMediaFile.Accessor(getRoot(byteBuffer: &byteBuffer) as TelegramCore_TelegramMediaFile, serializedFileData)
} else {
let file = decoder.decodeObjectForKey("f") as! TelegramMediaFile
self.file = TelegramMediaFile.Accessor(file)
}
self.indexKeys = decoder.decodeBytesArrayForKey("s")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.index.index, forKey: "i.n")
encoder.encodeInt64(self.index.id, forKey: "i.i")
encoder.encodeObject(self.file, forKey: "f")
encoder.encodeData(self.serializedFile, forKey: "fd")
if let serializedFile = self.file._wrappedData {
encoder.encodeData(serializedFile, forKey: "fd")
} else if let file = self.file._wrappedFile {
var builder = FlatBufferBuilder(initialSize: 1024)
let value = file.encodeToFlatBuffers(builder: &builder)
builder.finish(offset: value)
let serializedFile = builder.data
encoder.encodeData(serializedFile, forKey: "fd")
} else {
preconditionFailure()
}
encoder.encodeBytesArray(self.indexKeys, forKey: "s")
}
public static func ==(lhs: StickerPackItem, rhs: StickerPackItem) -> Bool {
return lhs.index == rhs.index && lhs.file == rhs.file && lhs.indexKeys == rhs.indexKeys
if lhs.index != rhs.index {
return false
}
if lhs.indexKeys != rhs.indexKeys {
return false
}
if lhs.file != rhs.file {
return false
}
return true
}
public func getStringRepresentationsOfIndexKeys() -> [String] {

View File

@ -475,7 +475,7 @@ public enum TelegramMediaFileAttribute: PostboxCoding, Equatable {
init(flatBuffersData data: Data) throws {
var byteBuffer = ByteBuffer(data: data)
let flatBuffersObject: TelegramCore_TelegramMediaFileAttribute = try getCheckedRoot(byteBuffer: &byteBuffer)
let flatBuffersObject: TelegramCore_TelegramMediaFileAttribute = getRoot(byteBuffer: &byteBuffer)
try self.init(flatBuffersObject: flatBuffersObject)
}
@ -672,6 +672,43 @@ public enum TelegramMediaFileDecodingError: Error {
}
public final class TelegramMediaFile: Media, Equatable, Codable {
public struct Accessor: Equatable {
let _wrappedFile: TelegramMediaFile?
let _wrapped: TelegramCore_TelegramMediaFile?
let _wrappedData: Data?
public init(_ wrapped: TelegramCore_TelegramMediaFile, _ _wrappedData: Data) {
self._wrapped = wrapped
self._wrappedData = _wrappedData
self._wrappedFile = nil
}
public init(_ wrapped: TelegramMediaFile) {
self._wrapped = nil
self._wrappedData = nil
self._wrappedFile = wrapped
}
public func _parse() -> TelegramMediaFile {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile
} else {
return try! TelegramMediaFile(flatBuffersObject: self._wrapped!)
}
}
public static func ==(lhs: TelegramMediaFile.Accessor, rhs: TelegramMediaFile.Accessor) -> Bool {
if let lhsWrappedFile = lhs._wrappedFile, let rhsWrappedFile = rhs._wrappedFile {
return lhsWrappedFile === rhsWrappedFile
} else if let lhsWrappedData = lhs._wrappedData, let rhsWrappedData = rhs._wrappedData {
return lhsWrappedData == rhsWrappedData
} else {
assertionFailure()
return false
}
}
}
enum CodingKeys: String, CodingKey {
case data
}
@ -807,14 +844,6 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
} else {
self.alternativeRepresentations = []
}
/*#if DEBUG
let fbData = self.encodeToFlatBuffersData()
var byteBuffer = ByteBuffer(data: fbData)
let flatBuffersObject: TelegramCore_TelegramMediaFile = try! getCheckedRoot(byteBuffer: &byteBuffer)
let fbObject = try! TelegramMediaFile(flatBuffersObject: flatBuffersObject)
assert(self == fbObject)
#endif*/
}
public func encode(_ encoder: PostboxEncoder) {
@ -1313,3 +1342,450 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
public func ==(lhs: TelegramMediaFile, rhs: TelegramMediaFile) -> Bool {
return lhs.isEqual(to: rhs)
}
public extension TelegramMediaFile.Accessor {
var fileId: MediaId {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.fileId
}
return MediaId(namespace: self._wrapped!.fileId.namespace, id: self._wrapped!.fileId.id)
}
var id: MediaId {
return self.fileId
}
var fileName: String? {
get {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.fileName
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeFilename {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_FileName.self) {
return value.fileName
}
}
}
return nil
}
}
var isSticker: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isSticker
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeSticker {
return true
}
}
return false
}
var isStaticSticker: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isStaticSticker
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeSticker {
if self._wrapped!.size != Int64.min, self._wrapped!.size < 300 * 1024 {
return !isAnimatedSticker
} else if self._wrapped!.size == Int64.min {
return !isAnimatedSticker
}
return false
}
}
return false
}
var isStaticEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isStaticEmoji
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
return self._wrapped!.mimeType == "image/webp"
}
}
return false
}
var isVideo: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isVideo
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeVideo {
return true
}
}
return false
}
var isInstantVideo: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isInstantVideo
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeVideo {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Video.self) {
return TelegramMediaVideoFlags(rawValue: value.flags).contains(.instantRoundVideo)
}
}
}
return false
}
var preloadSize: Int32? {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.preloadSize
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeVideo {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Video.self) {
return value.preloadSize == 0 ? nil : value.preloadSize
}
}
}
return nil
}
var isAnimated: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isAnimated
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeAnimated {
return true
}
}
return false
}
var isAnimatedSticker: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isAnimatedSticker
}
if self._wrapped!.mimeType == "application/x-tgsticker" && self.fileName != nil {
return true
}
return false
}
var isPremiumSticker: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isPremiumSticker
}
for i in 0 ..< self._wrapped!.videoThumbnailsCount {
let thumbnail = self._wrapped!.videoThumbnails(at: i)!
if thumbnail.resource.valueType == .telegrammediaresourceClouddocumentsizemediaresource {
if let value = thumbnail.resource.value(type: TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.self) {
if value.sizeSpec == "f" {
return true
}
}
}
}
return false
}
var noPremium: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.noPremium
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeNopremium {
return true
}
}
return false
}
var premiumEffect: TelegramMediaFile.VideoThumbnail? {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.premiumEffect
}
for i in 0 ..< self._wrapped!.videoThumbnailsCount {
let thumbnail = self._wrapped!.videoThumbnails(at: i)!
if thumbnail.resource.valueType == .telegrammediaresourceClouddocumentsizemediaresource {
if let value = thumbnail.resource.value(type: TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.self) {
if value.sizeSpec == "f" {
return try! TelegramMediaFile.VideoThumbnail(flatBuffersObject: thumbnail)
}
}
}
}
return nil
}
var isVideoSticker: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isVideoSticker
}
if self._wrapped!.mimeType == "video/webm" {
var hasSticker = false
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeSticker {
hasSticker = true
break
} else if attribute.valueType == .telegrammediafileattributeCustomemoji {
hasSticker = true
break
}
}
return hasSticker
}
return false
}
var isCustomEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isCustomEmoji
}
var hasSticker = false
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
hasSticker = true
break
}
}
return hasSticker
}
var customEmojiAlt: String? {
if let _wrappedFile = self._wrappedFile {
for attribute in _wrappedFile.attributes {
if case let .CustomEmoji(_, _, alt, _) = attribute {
return alt
}
}
return nil
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_CustomEmoji.self) {
return value.alt
}
break
}
}
return nil
}
var stickerDisplayText: String? {
if let _wrappedFile = self._wrappedFile {
for attribute in _wrappedFile.attributes {
if case let .Sticker(displayText, _, _) = attribute {
return displayText
}
}
return nil
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeSticker {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Sticker.self) {
return value.displayText
}
}
}
return nil
}
var isCustomTemplateEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isCustomTemplateEmoji
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_CustomEmoji.self) {
let isSingleColor = value.isSingleColor
if isSingleColor {
return true
}
if let packReference = value.packReference {
if packReference.valueType == .stickerpackreferenceId {
if let value = packReference.value(type: TelegramCore_StickerPackReference_Id.self) {
if value.id == 1269403972611866647 {
return true
}
}
}
}
}
}
}
return false
}
var internal_isHardcodedTemplateEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
for attribute in _wrappedFile.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
return true
}
default:
break
}
}
}
return false
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_CustomEmoji.self) {
if let packReference = value.packReference {
if packReference.valueType == .stickerpackreferenceId {
if let value = packReference.value(type: TelegramCore_StickerPackReference_Id.self) {
if value.id == 773947703670341676 || value.id == 2964141614563343 {
return true
}
}
}
}
}
}
}
return false
}
var isPremiumEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isPremiumEmoji
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_CustomEmoji.self) {
return value.isPremium
}
}
}
return false
}
var isVideoEmoji: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isVideoEmoji
}
if self._wrapped!.mimeType == "video/webm" {
var hasSticker = false
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeCustomemoji {
hasSticker = true
break
}
}
return hasSticker
}
return false
}
var hasLinkedStickers: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.hasLinkedStickers
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeHaslinkedstickers {
return true
}
}
return false
}
var isMusic: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isMusic
}
var hasNonVoiceAudio = false
var hasVideo = false
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeAudio {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Audio.self) {
if !value.isVoice {
hasNonVoiceAudio = true
}
}
} else if attribute.valueType == .telegrammediafileattributeVideo {
hasVideo = true
}
}
return hasNonVoiceAudio && !hasVideo
}
var isVoice: Bool {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.isVoice
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeAudio {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Audio.self) {
return value.isVoice
}
}
}
return false
}
var dimensions: PixelDimensions? {
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.dimensions
}
for i in 0 ..< self._wrapped!.attributesCount {
let attribute = self._wrapped!.attributes(at: i)!
if attribute.valueType == .telegrammediafileattributeVideo {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_Video.self) {
return PixelDimensions(width: value.width, height: value.height)
}
} else if attribute.valueType == .telegrammediafileattributeImagesize {
if let value = attribute.value(type: TelegramCore_TelegramMediaFileAttribute_ImageSize.self) {
return PixelDimensions(width: value.width, height: value.height)
}
}
}
if self.isAnimatedSticker {
return PixelDimensions(width: 512, height: 512)
} else {
return nil
}
}
var immediateThumbnailData: Data? {
//TODO:release defer parsing
if let _wrappedFile = self._wrappedFile {
return _wrappedFile.immediateThumbnailData
}
return _wrapped!.immediateThumbnailData.isEmpty ? nil : Data(_wrapped!.immediateThumbnailData)
}
}

View File

@ -75,7 +75,7 @@ func _internal_randomGreetingSticker(account: Account) -> Signal<FoundStickerIte
|> map { items -> FoundStickerItem? in
if let randomItem = items?.randomElement(), let item = randomItem.contents.get(RecentMediaItem.self) {
let file = item.media
return FoundStickerItem(file: file, stringRepresentations: [])
return FoundStickerItem(file: file._parse(), stringRepresentations: [])
}
return nil
}
@ -107,7 +107,7 @@ func _internal_searchStickers(account: Account, query: String?, emoticon: [Strin
for representation in item.stringRepresentations {
for queryItem in emoticon {
if representation.hasPrefix(queryItem) {
result.append(FoundStickerItem(file: item.file, stringRepresentations: item.stringRepresentations))
result.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: item.stringRepresentations))
break
}
}
@ -131,7 +131,7 @@ func _internal_searchStickers(account: Account, query: String?, emoticon: [Strin
if !currentItems.contains(file.fileId) {
currentItems.insert(file.fileId)
for case let .Sticker(displayText, _, _) in file.attributes {
if let displayText = file.stickerDisplayText {
for queryItem in emoticon {
if displayText.hasPrefix(queryItem) {
matchingRecentItemsIds.insert(file.fileId)
@ -140,9 +140,9 @@ func _internal_searchStickers(account: Account, query: String?, emoticon: [Strin
}
recentItemsIds.insert(file.fileId)
if file.isAnimatedSticker || file.isVideoSticker {
recentAnimatedItems.append(file)
recentAnimatedItems.append(file._parse())
} else {
recentItems.append(file)
recentItems.append(file._parse())
}
break
}
@ -167,18 +167,18 @@ func _internal_searchStickers(account: Account, query: String?, emoticon: [Strin
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
if !recentItemsIds.contains(item.file.fileId) {
if item.file.isPremiumSticker {
installedPremiumItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedPremiumItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
} else if item.file.isAnimatedSticker || item.file.isVideoSticker {
installedAnimatedItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedAnimatedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
} else {
installedItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
}
} else {
matchingRecentItemsIds.insert(item.file.fileId)
if item.file.isAnimatedSticker || item.file.isVideoSticker {
recentAnimatedItems.append(item.file)
recentAnimatedItems.append(item.file._parse())
} else {
recentItems.append(item.file)
recentItems.append(item.file._parse())
}
}
}
@ -504,13 +504,13 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
if let item = entry.contents.get(SavedStickerItem.self) {
if case .premium = category.kind {
if item.file.isPremiumSticker {
result.append(FoundStickerItem(file: item.file, stringRepresentations: item.stringRepresentations))
result.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: item.stringRepresentations))
}
} else {
for representation in item.stringRepresentations {
for queryItem in query {
if representation.hasPrefix(queryItem) {
result.append(FoundStickerItem(file: item.file, stringRepresentations: item.stringRepresentations))
result.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: item.stringRepresentations))
break
}
}
@ -535,7 +535,7 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
if !currentItems.contains(file.fileId) {
currentItems.insert(file.fileId)
for case let .Sticker(displayText, _, _) in file.attributes {
if let displayText = file.stickerDisplayText {
if case .premium = category.kind {
if file.isPremiumSticker {
matchingRecentItemsIds.insert(file.fileId)
@ -550,9 +550,9 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
}
recentItemsIds.insert(file.fileId)
if file.isAnimatedSticker || file.isVideoSticker {
recentAnimatedItems.append(file)
recentAnimatedItems.append(file._parse())
} else {
recentItems.append(file)
recentItems.append(file._parse())
}
break
}
@ -585,18 +585,18 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
if !recentItemsIds.contains(item.file.fileId) {
if item.file.isPremiumSticker {
installedPremiumItems.append(FoundStickerItem(file: item.file, stringRepresentations: []))
installedPremiumItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: []))
} else if item.file.isAnimatedSticker || item.file.isVideoSticker {
installedAnimatedItems.append(FoundStickerItem(file: item.file, stringRepresentations: []))
installedAnimatedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: []))
} else {
installedItems.append(FoundStickerItem(file: item.file, stringRepresentations: []))
installedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: []))
}
} else {
matchingRecentItemsIds.insert(item.file.fileId)
if item.file.isAnimatedSticker || item.file.isVideoSticker {
recentAnimatedItems.append(item.file)
recentAnimatedItems.append(item.file._parse())
} else {
recentItems.append(item.file)
recentItems.append(item.file._parse())
}
}
}
@ -614,18 +614,18 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
if !recentItemsIds.contains(item.media.fileId) {
if item.media.isPremiumSticker {
installedPremiumItems.append(FoundStickerItem(file: item.media, stringRepresentations: []))
installedPremiumItems.append(FoundStickerItem(file: item.media._parse(), stringRepresentations: []))
} else if item.media.isAnimatedSticker || item.media.isVideoSticker {
installedAnimatedItems.append(FoundStickerItem(file: item.media, stringRepresentations: []))
installedAnimatedItems.append(FoundStickerItem(file: item.media._parse(), stringRepresentations: []))
} else {
installedItems.append(FoundStickerItem(file: item.media, stringRepresentations: []))
installedItems.append(FoundStickerItem(file: item.media._parse(), stringRepresentations: []))
}
} else {
matchingRecentItemsIds.insert(item.media.fileId)
if item.media.isAnimatedSticker || item.media.isVideoSticker {
recentAnimatedItems.append(item.media)
recentAnimatedItems.append(item.media._parse())
} else {
recentItems.append(item.media)
recentItems.append(item.media._parse())
}
}
}
@ -639,18 +639,18 @@ func _internal_searchStickers(account: Account, category: EmojiSearchCategories.
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
if !recentItemsIds.contains(item.file.fileId) {
if item.file.isPremiumSticker {
installedPremiumItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedPremiumItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
} else if item.file.isAnimatedSticker || item.file.isVideoSticker {
installedAnimatedItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedAnimatedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
} else {
installedItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
installedItems.append(FoundStickerItem(file: item.file._parse(), stringRepresentations: stringRepresentations))
}
} else {
matchingRecentItemsIds.insert(item.file.fileId)
if item.file.isAnimatedSticker || item.file.isVideoSticker {
recentAnimatedItems.append(item.file)
recentAnimatedItems.append(item.file._parse())
} else {
recentItems.append(item.file)
recentItems.append(item.file._parse())
}
}
}
@ -908,7 +908,7 @@ func _internal_searchEmoji(account: Account, query: String?, emoticon: [String],
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
for stringRepresentation in stringRepresentations {
if querySet.contains(stringRepresentation) {
installedItems.append(FoundStickerItem(file: file, stringRepresentations: stringRepresentations))
installedItems.append(FoundStickerItem(file: file._parse(), stringRepresentations: stringRepresentations))
break
}
}

View File

@ -36,7 +36,8 @@ func _internal_addStickerPackInteractively(postbox: Postbox, info: StickerPackCo
var indexedItems: [ItemCollectionItem] = []
for item in items {
indexedItems.append(StickerPackItem(index: ItemCollectionItemIndex(index: Int32(indexedItems.count), id: item.index.id), file: item.file, indexKeys: item.indexKeys))
let item = StickerPackItem(index: ItemCollectionItemIndex(index: Int32(indexedItems.count), id: item.index.id), file: item.file._parse(), indexKeys: item.indexKeys)
indexedItems.append(item)
}
transaction.replaceItemCollectionItems(collectionId: mappedInfo.id, items: indexedItems)
}

View File

@ -114,7 +114,7 @@ final class AvatarEditorScreenComponent: Component {
self.fileDisposable = (context.engine.stickers.loadedStickerPack(reference: packReference, forceActualized: false)
|> map { pack -> TelegramMediaFile? in
if case let .result(_, items, _) = pack, let item = items.first(where: { $0.file.fileId.id == fileId }) {
return item.file
return item.file._parse()
}
return nil
}
@ -249,7 +249,7 @@ final class AvatarEditorScreenComponent: Component {
self.data = data
if wasEmpty && self.state?.selectedFile == nil {
self.state?.selectedFile = data.emoji.panelItemGroups.first?.items.first?.itemFile
self.state?.selectedFile = data.emoji.panelItemGroups.first?.items.first?.itemFile?._parse()
}
let updateSearchQuery: (EmojiPagerContentComponent.SearchQuery?) -> Void = { [weak self] query in
@ -295,7 +295,7 @@ final class AvatarEditorScreenComponent: Component {
|> map { view, stickers -> [EmojiPagerContentComponent.ItemGroup] in
let hasPremium = true
var emoji: [(String, TelegramMediaFile?, String)] = []
var emoji: [(String, TelegramMediaFile.Accessor?, String)] = []
var existingEmoticons = Set<String>()
var allEmoticons: [String: String] = [:]
@ -310,18 +310,13 @@ final class AvatarEditorScreenComponent: Component {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
emoji.append((alt, item.file, keyword))
} else if alt == query {
emoji.append((alt, item.file, alt))
}
if let alt = item.file.customEmojiAlt {
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
emoji.append((alt, item.file, keyword))
} else if alt == query {
emoji.append((alt, item.file, alt))
}
default:
break
}
}
}
@ -355,11 +350,11 @@ final class AvatarEditorScreenComponent: Component {
}
existingIds.insert(sticker.file.fileId)
let animationData = EntityKeyboardAnimationData(file: sticker.file)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(sticker.file))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: sticker.file,
itemFile: TelegramMediaFile.Accessor(sticker.file),
subgroupId: nil,
icon: .none,
tintMode: .none
@ -441,11 +436,12 @@ final class AvatarEditorScreenComponent: Component {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -520,7 +516,7 @@ final class AvatarEditorScreenComponent: Component {
guard let self, let _ = item.itemFile else {
return
}
self.state?.selectedFile = item.itemFile
self.state?.selectedFile = item.itemFile?._parse()
self.state?.updated(transition: .easeInOut(duration: 0.2))
},
deleteBackwards: nil,
@ -655,7 +651,7 @@ final class AvatarEditorScreenComponent: Component {
guard let self, let _ = item.itemFile else {
return
}
self.state?.selectedFile = item.itemFile
self.state?.selectedFile = item.itemFile?._parse()
self.state?.updated(transition: .easeInOut(duration: 0.2))
},
deleteBackwards: nil,

View File

@ -151,7 +151,7 @@ public final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNod
guard let stickerItem = self.stickerItem else {
return
}
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil, [])
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file._parse()), false, self.view, self.stickerNode.bounds, nil, [])
}
public func updateLayout(interfaceState: ChatPresentationInterfaceState, subject: ChatEmptyNode.Subject, size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
@ -359,7 +359,7 @@ public final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNodeS
guard let stickerItem = self.stickerItem else {
return
}
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil, [])
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file._parse()), false, self.view, self.stickerNode.bounds, nil, [])
}
public func updateLayout(interfaceState: ChatPresentationInterfaceState, subject: ChatEmptyNode.Subject, size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {

View File

@ -266,6 +266,8 @@ public final class ChatMediaInputStickerGridItemNode: GridItemNode {
}
if let dimensions = item.stickerItem.file.dimensions {
let parsedStickerItemFile = item.stickerItem.file._parse()
if item.stickerItem.file.isAnimatedSticker || item.stickerItem.file.isVideoSticker {
if self.animationNode == nil {
let animationNode = DefaultAnimatedStickerNodeImpl()
@ -283,12 +285,12 @@ public final class ChatMediaInputStickerGridItemNode: GridItemNode {
let dimensions = item.stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedSize = item.large ? CGSize(width: 384.0, height: 384.0) : CGSize(width: 160.0, height: 160.0)
if item.stickerItem.file.isVideoSticker {
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: item.stickerItem.file, small: false, synchronousLoad: synchronousLoads && isVisible))
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: parsedStickerItemFile, small: false, synchronousLoad: synchronousLoads && isVisible))
} else {
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .other, file: item.stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(fittedSize)))
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, userLocation: .other, file: parsedStickerItemFile, small: false, size: dimensions.cgSize.aspectFitted(fittedSize)))
}
self.updateVisibility()
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: item.stickerItem.file.resource).startStrict())
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(parsedStickerItemFile), resource: parsedStickerItemFile.resource).startStrict())
} else {
if let animationNode = self.animationNode {
animationNode.visibility = false
@ -297,8 +299,8 @@ public final class ChatMediaInputStickerGridItemNode: GridItemNode {
self.imageNode.isHidden = false
self.didSetUpAnimationNode = false
}
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: item.stickerItem.file, small: !item.large, synchronousLoad: synchronousLoads && isVisible))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: !item.large)).startStrict())
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, userLocation: .other, file: parsedStickerItemFile, small: !item.large, synchronousLoad: synchronousLoads && isVisible))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: stickerPackFileReference(parsedStickerItemFile), resource: chatMessageStickerResource(file: parsedStickerItemFile, small: !item.large)).startStrict())
}
self.currentState = (item.context, item.stickerItem, dimensions.cgSize)
@ -405,7 +407,7 @@ public final class ChatMediaInputStickerGridItemNode: GridItemNode {
if let interfaceInteraction = self.interfaceInteraction, let (_, item, _) = self.currentState, case .ended = recognizer.state {
if let isLocked = self.isLocked, isLocked {
} else {
let _ = interfaceInteraction.sendSticker(.standalone(media: item.file), false, false, nil, false, self.view, self.bounds, nil, [])
let _ = interfaceInteraction.sendSticker(.standalone(media: item.file._parse()), false, false, nil, false, self.view, self.bounds, nil, [])
self.imageNode.layer.animateAlpha(from: 0.5, to: 1.0, duration: 1.0)
}
}
@ -438,7 +440,7 @@ public final class ChatMediaInputStickerGridItemNode: GridItemNode {
let dimensions = item.stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fitSize = item.large ? CGSize(width: 384.0, height: 384.0) : CGSize(width: 160.0, height: 160.0)
let fittedDimensions = dimensions.cgSize.aspectFitted(fitSize)
animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: item.stickerItem.file.resource, isVideo: item.stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: item.stickerItem.file._parse().resource, isVideo: item.stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
}
}
}

View File

@ -480,10 +480,10 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
if emojiFile == nil {
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file._parse()
}
if emojiFile == nil {
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file._parse()
}
if item.message.text.count == 1, (item.message.textEntitiesAttribute?.entities ?? []).isEmpty && emojiFile != nil {
@ -544,7 +544,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let animationItems = animationItems {
for (_, animationItem) in animationItems {
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file)).startStrict())
self.disposables.add(freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .peer(item.message.id.peerId), fileReference: .standalone(media: animationItem.file._parse())).startStrict())
}
}
}
@ -1965,7 +1965,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
return
}
self.playEffectAnimation(resource: file.resource)
self.playEffectAnimation(resource: file._parse().resource)
}
private var playedPremiumStickerAnimation = false

View File

@ -733,7 +733,7 @@ public class ChatMessageDateAndStatusNode: ASDisplayNode {
if let availableReactions = arguments.availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction.value {
centerAnimation = availableReaction.centerAnimation
centerAnimation = availableReaction.centerAnimation?._parse()
break
}
}

View File

@ -156,7 +156,7 @@ public final class MessageReactionButtonsNode: ASDisplayNode {
if let availableReactions = availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction.value {
centerAnimation = availableReaction.centerAnimation
centerAnimation = availableReaction.centerAnimation?._parse()
break
}
}
@ -167,7 +167,7 @@ public final class MessageReactionButtonsNode: ASDisplayNode {
if let availableReactions = availableReactions {
for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction.value {
centerAnimation = availableReaction.centerAnimation
centerAnimation = availableReaction.centerAnimation?._parse()
break
}
}

View File

@ -1007,9 +1007,9 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
let (emoji, fitz) = item.message.text.basicEmoji
var emojiFile: TelegramMediaFile?
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file._parse()
if emojiFile == nil {
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file._parse()
}
if let emojiFile = emojiFile {

View File

@ -1070,12 +1070,12 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
} else {
defaultWallpaper = nil
}
entries.append(ThemeSettingsThemeEntry(index: 0, emoticon: defaultEmoticon, emojiFile: animatedEmojiStickers[defaultEmoticon]?.first?.file, themeReference: .builtin(isDarkAppearance ? .night : .dayClassic), nightMode: isDarkAppearance, selected: selectedEmoticon == defaultEmoticon, theme: presentationData.theme, strings: presentationData.strings, wallpaper: defaultWallpaper, message: isMessage))
entries.append(ThemeSettingsThemeEntry(index: 0, emoticon: defaultEmoticon, emojiFile: animatedEmojiStickers[defaultEmoticon]?.first?.file._parse(), themeReference: .builtin(isDarkAppearance ? .night : .dayClassic), nightMode: isDarkAppearance, selected: selectedEmoticon == defaultEmoticon, theme: presentationData.theme, strings: presentationData.strings, wallpaper: defaultWallpaper, message: isMessage))
for theme in themes {
guard let emoticon = theme.emoticon else {
continue
}
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file, themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil, message: isMessage))
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file._parse(), themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil, message: isMessage))
}
let wallpaper: TelegramWallpaper

View File

@ -94,7 +94,7 @@ public final class ChatShareMessageTagView: UIView, UndoOverlayControllerAdditio
case .builtin:
for reaction in availableReactions.reactions {
if reaction.value == updateReaction.reaction {
file = reaction.centerAnimation
file = reaction.centerAnimation?._parse()
break
}
}
@ -103,7 +103,7 @@ public final class ChatShareMessageTagView: UIView, UndoOverlayControllerAdditio
case .stars:
for reaction in availableReactions.reactions {
if reaction.value == updateReaction.reaction {
file = reaction.centerAnimation
file = reaction.centerAnimation?._parse()
break
}
}

View File

@ -142,7 +142,7 @@ public final class ManagedDiceAnimationNode: ManagedAnimationNode {
case let .result(_, items, _):
var emojiStickers: [TelegramMediaFile] = []
for item in items {
emojiStickers.append(item.file)
emojiStickers.append(item.file._parse())
}
return .single(emojiStickers)
default:

View File

@ -156,12 +156,13 @@ public func tagMessageReactions(context: AccountContext, subPeerId: EnginePeer.I
}
existingIds.insert(.custom(file.fileId.id))
let itemFile = TelegramMediaFile.Accessor(file)
result.append(ReactionItem(
reaction: ReactionItem.Reaction(rawValue: .custom(file.fileId.id)),
appearAnimation: file,
stillAnimation: file,
listAnimation: file,
largeListAnimation: file,
appearAnimation: itemFile,
stillAnimation: itemFile,
listAnimation: itemFile,
largeListAnimation: itemFile,
applicationAnimation: nil,
largeApplicationAnimation: nil,
isCustom: true
@ -441,6 +442,7 @@ public func topMessageReactions(context: AccountContext, message: Message, subPe
break
case let .custom(fileId):
if let file = allowedReactionsAndFiles.files[fileId] {
let file = TelegramMediaFile.Accessor(file)
result.append(ReactionItem(
reaction: ReactionItem.Reaction(rawValue: .custom(file.fileId.id)),
appearAnimation: file,
@ -499,7 +501,7 @@ public func effectMessageReactions(context: AccountContext) -> Signal<[ReactionI
}
existingIds.insert(messageEffect.id)
let mainFile: TelegramMediaFile = messageEffect.effectSticker
let mainFile = TelegramMediaFile.Accessor(messageEffect.effectSticker)
result.append(ReactionItem(
reaction: ReactionItem.Reaction(rawValue: .custom(messageEffect.id)),

View File

@ -336,7 +336,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
continue
}
availableGifSearchEmojies.append(EntityKeyboardComponent.GifSearchEmoji(emoji: reaction, file: file, title: title))
availableGifSearchEmojies.append(EntityKeyboardComponent.GifSearchEmoji(emoji: reaction, file: file._parse(), title: title))
}
}
@ -649,7 +649,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
}
}
})
} else if let file = item.itemFile {
} else if let file = item.itemFile?._parse() {
var text = "."
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
@ -970,11 +970,11 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
if itemFile.isPremiumEmoji && !hasPremium {
continue
}
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
@ -1086,11 +1086,11 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
@ -1177,7 +1177,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
guard let interaction else {
return
}
guard let file = item.itemFile else {
guard let file = item.itemFile?._parse() else {
if case .icon(.add) = item.content {
interaction.openStickerEditor()
}
@ -1433,11 +1433,12 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: itemFile.isPremiumSticker ? .premium : .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -2316,10 +2317,10 @@ public final class EntityInputView: UIInputView, AttachmentTextInputPanelInputVi
if groupId == AnyHashable("featuredTop") {
} else {
if let file = item.itemFile {
if let file = item.itemFile?._parse() {
var text = "."
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, _, displayText, _):
text = displayText

View File

@ -568,7 +568,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
func itemAt(point: CGPoint) -> (ASDisplayNode, Any)? {
if !self.trendingPane.isHidden {
if let (itemNode, item) = self.trendingPane.itemAt(point: self.view.convert(point, to: self.trendingPane.view)) {
return (itemNode, StickerPreviewPeekItem.pack(item.file))
return (itemNode, StickerPreviewPeekItem.pack(item.file._parse()))
}
} else {
if let itemNode = self.gridNode.itemNodeAtPoint(self.view.convert(point, to: self.gridNode.view)) {
@ -576,7 +576,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
return (itemNode, StickerPreviewPeekItem.found(stickerItem))
} else if let itemNode = itemNode as? StickerPaneSearchGlobalItemNode {
if let (node, item) = itemNode.itemAt(point: self.view.convert(point, to: itemNode.view)) {
return (node, StickerPreviewPeekItem.pack(item.file))
return (node, StickerPreviewPeekItem.pack(item.file._parse()))
}
}
}

View File

@ -23,20 +23,17 @@ import TelegramNotices
private func randomGenericReactionEffect(context: AccountContext) -> Signal<String?, NoError> {
return context.engine.stickers.loadedStickerPack(reference: .emojiGenericAnimations, forceActualized: false)
|> map { result -> [TelegramMediaFile]? in
|> map { result -> TelegramMediaFile? in
switch result {
case let .result(_, items, _):
return items.map(\.file)
return items.randomElement()?.file._parse()
default:
return nil
}
}
|> take(1)
|> mapToSignal { items -> Signal<String?, NoError> in
guard let items = items else {
return .single(nil)
}
guard let file = items.randomElement() else {
|> mapToSignal { file -> Signal<String?, NoError> in
guard let file else {
return .single(nil)
}
return Signal { subscriber in
@ -380,14 +377,9 @@ public final class EmojiStatusSelectionController: ViewController {
let filterList: [String] = ["😖", "😫", "🫠", "😨", ""]
for featuredEmojiPack in featuredEmojiPacks {
for item in featuredEmojiPack.topItems {
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if filterList.contains(alt) {
filteredFiles.append(item.file)
}
default:
break
if let alt = item.file.customEmojiAlt {
if filterList.contains(alt) {
filteredFiles.append(item.file._parse())
}
}
}
@ -531,7 +523,7 @@ public final class EmojiStatusSelectionController: ViewController {
)
|> take(1)
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var result: [(String, TelegramMediaFile.Accessor?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
@ -544,18 +536,13 @@ public final class EmojiStatusSelectionController: ViewController {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
if let alt = item.file.customEmojiAlt {
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
default:
break
}
}
}
@ -626,11 +613,12 @@ public final class EmojiStatusSelectionController: ViewController {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -801,7 +789,8 @@ public final class EmojiStatusSelectionController: ViewController {
if itemFile.isCustomTemplateEmoji {
useCleanEffect = true
}
for attribute in itemFile.attributes {
for attribute in itemFile._parse().attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
@ -843,8 +832,8 @@ public final class EmojiStatusSelectionController: ViewController {
context: self.context,
userLocation: .other,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemFile.fileId.id, file: itemFile),
file: item.itemFile,
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemFile.fileId.id, file: itemFile._parse()),
file: item.itemFile?._parse(),
cache: animationCache,
renderer: animationRenderer,
placeholderColor: UIColor(white: 0.0, alpha: 0.0),
@ -1149,7 +1138,7 @@ public final class EmojiStatusSelectionController: ViewController {
}
}
if let previewItem = self.previewItem, let itemFile = previewItem.item.displayFile {
if let previewItem = self.previewItem, let itemFile = previewItem.item.displayFile?._parse() {
let previewScreenView: ComponentView<Empty>
var previewScreenTransition = transition
if let current = self.previewScreenView {
@ -1202,14 +1191,8 @@ public final class EmojiStatusSelectionController: ViewController {
} else {
var emojiString: String?
if let itemFile = previewItem.item.itemFile {
attributeLoop: for attribute in itemFile.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
emojiString = alt
break attributeLoop
default:
break
}
if let alt = itemFile.customEmojiAlt {
emojiString = alt
}
}
@ -1222,7 +1205,7 @@ public final class EmojiStatusSelectionController: ViewController {
}
for reaction in availableReactions.reactions {
if case let .builtin(value) = reaction.value, value == emojiString {
if let aroundAnimation = reaction.aroundAnimation {
if let aroundAnimation = reaction.aroundAnimation?._parse() {
return context.account.postbox.mediaBox.resourceData(aroundAnimation.resource)
|> take(1)
|> map { data -> String? in
@ -1244,7 +1227,7 @@ public final class EmojiStatusSelectionController: ViewController {
return
}
let _ = (strongSelf.context.engine.accountData.setEmojiStatus(file: previewItem.item.itemFile, expirationDate: expirationDate)
let _ = (strongSelf.context.engine.accountData.setEmojiStatus(file: previewItem.item.itemFile?._parse(), expirationDate: expirationDate)
|> deliverOnMainQueue).start()
strongSelf.animateOutToStatus(item: previewItem.item, sourceLayer: result.sourceView.layer, customEffectFile: filePath, destinationView: destinationView, fromBackground: true)
@ -1351,13 +1334,13 @@ public final class EmojiStatusSelectionController: ViewController {
}
})
} else {
let _ = (self.context.engine.accountData.setEmojiStatus(file: item?.itemFile, expirationDate: nil)
let _ = (self.context.engine.accountData.setEmojiStatus(file: item?.itemFile?._parse(), expirationDate: nil)
|> deliverOnMainQueue).start()
}
case let .backgroundSelection(completion):
completion(item?.itemFile)
completion(item?.itemFile?._parse())
case let .customStatusSelection(completion):
completion(item?.itemFile, nil)
completion(item?.itemFile?._parse(), nil)
case let .quickReactionSelection(completion):
if let item = item, let itemFile = item.itemFile {
var selectedReaction: MessageReaction.Reaction?
@ -1397,14 +1380,8 @@ public final class EmojiStatusSelectionController: ViewController {
if animateOutToView, let item = item, let destinationView = controller.destinationItemView() {
var emojiString: String?
if let itemFile = item.itemFile {
attributeLoop: for attribute in itemFile.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
emojiString = alt
break attributeLoop
default:
break
}
if let alt = itemFile.customEmojiAlt {
emojiString = alt
}
}
@ -1417,7 +1394,7 @@ public final class EmojiStatusSelectionController: ViewController {
}
for reaction in availableReactions.reactions {
if case let .builtin(value) = reaction.value, value == emojiString {
if let aroundAnimation = reaction.aroundAnimation {
if let aroundAnimation = reaction.aroundAnimation?._parse() {
return context.account.postbox.mediaBox.resourceData(aroundAnimation.resource)
|> take(1)
|> map { data -> String? in
@ -1561,11 +1538,15 @@ private func generateParabollicMotionKeyframes(from sourcePoint: CGPoint, to tar
}
extension EmojiPagerContentComponent.Item {
var displayFile: TelegramMediaFile? {
var displayFile: TelegramMediaFile.Accessor? {
if let file = self.itemFile {
return file
} else if let gift = self.itemGift {
return gift.itemFile
if let itemFile = gift.itemFile {
return TelegramMediaFile.Accessor(itemFile)
} else {
return nil
}
} else {
return nil
}

View File

@ -77,7 +77,7 @@ public final class EmojiSuggestionsComponent: Component {
if stringRepresentation == query || (!normalizedQuery.isEmpty && stringRepresentation == normalizedQuery) {
if !existingIds.contains(item.file.fileId) {
existingIds.insert(item.file.fileId)
result.append(item.file)
result.append(item.file._parse())
}
break
}
@ -86,19 +86,14 @@ public final class EmojiSuggestionsComponent: Component {
for featuredPack in featuredEmojiPacks {
for item in featuredPack.topItems {
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if alt == query || (!normalizedQuery.isEmpty && alt == normalizedQuery) {
if !item.file.isPremiumEmoji || hasPremium {
if !existingIds.contains(item.file.fileId) {
existingIds.insert(item.file.fileId)
result.append(item.file)
}
if let alt = item.file.customEmojiAlt {
if alt == query || (!normalizedQuery.isEmpty && alt == normalizedQuery) {
if !item.file.isPremiumEmoji || hasPremium {
if !existingIds.contains(item.file.fileId) {
existingIds.insert(item.file.fileId)
result.append(item.file._parse())
}
}
default:
break
}
}
}

View File

@ -177,19 +177,21 @@ public final class EmojiKeyboardItemLayer: MultiAnimationRenderTarget {
switch content {
case let .animation(animationData):
let animationDataResource = animationData.resource._parse()
let loadAnimation: () -> Void = { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.disposable = renderer.add(target: strongSelf, cache: cache, itemId: animationData.resource.resource.id.stringRepresentation, unique: false, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationData.resource, type: animationData.type.animationCacheAnimationType, keyframeOnly: pixelSize.width >= 120.0, customColor: animationData.isTemplate ? .white : nil))
strongSelf.disposable = renderer.add(target: strongSelf, cache: cache, itemId: animationDataResource.resource.id.stringRepresentation, unique: false, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationDataResource, type: animationData.type.animationCacheAnimationType, keyframeOnly: pixelSize.width >= 120.0, customColor: animationData.isTemplate ? .white : nil))
}
if attemptSynchronousLoad {
if !renderer.loadFirstFrameSynchronously(target: self, cache: cache, itemId: animationData.resource.resource.id.stringRepresentation, size: pixelSize) {
if !renderer.loadFirstFrameSynchronously(target: self, cache: cache, itemId: animationDataResource.resource.id.stringRepresentation, size: pixelSize) {
self.updateDisplayPlaceholder(displayPlaceholder: true)
self.fetchDisposable = renderer.loadFirstFrame(target: self, cache: cache, itemId: animationData.resource.resource.id.stringRepresentation, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationData.resource, type: animationData.type.animationCacheAnimationType, keyframeOnly: true, customColor: animationData.isTemplate ? .white : nil), completion: { [weak self] success, isFinal in
self.fetchDisposable = renderer.loadFirstFrame(target: self, cache: cache, itemId: animationDataResource.resource.id.stringRepresentation, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationDataResource, type: animationData.type.animationCacheAnimationType, keyframeOnly: true, customColor: animationData.isTemplate ? .white : nil), completion: { [weak self] success, isFinal in
if !isFinal {
if !success {
Queue.mainQueue().async {
@ -219,7 +221,7 @@ public final class EmojiKeyboardItemLayer: MultiAnimationRenderTarget {
loadAnimation()
}
} else {
self.fetchDisposable = renderer.loadFirstFrame(target: self, cache: cache, itemId: animationData.resource.resource.id.stringRepresentation, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationData.resource, type: animationData.type.animationCacheAnimationType, keyframeOnly: true, customColor: animationData.isTemplate ? .white : nil), completion: { [weak self] success, isFinal in
self.fetchDisposable = renderer.loadFirstFrame(target: self, cache: cache, itemId: animationDataResource.resource.id.stringRepresentation, size: pixelSize, fetch: animationCacheFetchFile(context: context, userLocation: .other, userContentType: .sticker, resource: animationDataResource, type: animationData.type.animationCacheAnimationType, keyframeOnly: true, customColor: animationData.isTemplate ? .white : nil), completion: { [weak self] success, isFinal in
if !isFinal {
if !success {
Queue.mainQueue().async {

View File

@ -28,9 +28,9 @@ import GenerateStickerPlaceholderImage
public struct EmojiComponentReactionItem: Equatable {
public var reaction: MessageReaction.Reaction
public var file: TelegramMediaFile
public var file: TelegramMediaFile.Accessor
public init(reaction: MessageReaction.Reaction, file: TelegramMediaFile) {
public init(reaction: MessageReaction.Reaction, file: TelegramMediaFile.Accessor) {
self.reaction = reaction
self.file = file
}
@ -60,16 +60,35 @@ public final class EntityKeyboardAnimationData: Equatable {
}
}
public enum Resource: Equatable {
case resource(MediaResourceReference)
case file(PartialMediaReference?, TelegramMediaFile.Accessor)
func _parse() -> MediaResourceReference {
switch self {
case let .resource(resource):
return resource
case let .file(partialReference, file):
let file = file._parse()
if let partialReference {
return partialReference.mediaReference(file).resourceReference(file.resource)
} else {
return .standalone(resource: file.resource)
}
}
}
}
public let id: Id
public let type: ItemType
public let resource: MediaResourceReference
public let resource: Resource
public let dimensions: CGSize
public let immediateThumbnailData: Data?
public let isReaction: Bool
public let isTemplate: Bool
public let particleColor: UIColor?
public init(id: Id, type: ItemType, resource: MediaResourceReference, dimensions: CGSize, immediateThumbnailData: Data?, isReaction: Bool, isTemplate: Bool, particleColor: UIColor? = nil) {
public init(id: Id, type: ItemType, resource: Resource, dimensions: CGSize, immediateThumbnailData: Data?, isReaction: Bool, isTemplate: Bool, particleColor: UIColor? = nil) {
self.id = id
self.type = type
self.resource = resource
@ -80,7 +99,7 @@ public final class EntityKeyboardAnimationData: Equatable {
self.particleColor = particleColor
}
public convenience init(file: TelegramMediaFile, isReaction: Bool = false, partialReference: PartialMediaReference? = nil) {
public convenience init(file: TelegramMediaFile.Accessor, isReaction: Bool = false, partialReference: PartialMediaReference? = nil) {
let type: ItemType
if file.isVideoSticker || file.isVideoEmoji {
type = .video
@ -91,13 +110,8 @@ public final class EntityKeyboardAnimationData: Equatable {
}
let isTemplate = file.isCustomTemplateEmoji
let resourceReference: MediaResourceReference
if let partialReference {
resourceReference = partialReference.mediaReference(file).resourceReference(file.resource)
} else {
resourceReference = .standalone(resource: file.resource)
}
self.init(id: .file(file.fileId), type: type, resource: resourceReference, dimensions: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0), immediateThumbnailData: file.immediateThumbnailData, isReaction: isReaction, isTemplate: isTemplate)
let resource: Resource = .file(partialReference, file)
self.init(id: .file(file.fileId), type: type, resource: resource, dimensions: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0), immediateThumbnailData: file.immediateThumbnailData, isReaction: isReaction, isTemplate: isTemplate)
}
public convenience init?(gift: StarGift.UniqueGift) {
@ -113,7 +127,7 @@ public final class EntityKeyboardAnimationData: Equatable {
}
if let file, let color {
let resourceReference: MediaResourceReference = .standalone(resource: file.resource)
self.init(id: .gift(gift.slug), type: .lottie, resource: resourceReference, dimensions: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0), immediateThumbnailData: file.immediateThumbnailData, isReaction: false, isTemplate: false, particleColor: color)
self.init(id: .gift(gift.slug), type: .lottie, resource: .resource(resourceReference), dimensions: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0), immediateThumbnailData: file.immediateThumbnailData, isReaction: false, isTemplate: false, particleColor: color)
} else {
return nil
}
@ -124,7 +138,7 @@ public final class EntityKeyboardAnimationData: Equatable {
return true
}
if lhs.resource.resource.id != rhs.resource.resource.id {
if lhs.resource != rhs.resource {
return false
}
if lhs.dimensions != rhs.dimensions {
@ -401,7 +415,7 @@ public final class EmojiPagerContentComponent: Component {
public let animationData: EntityKeyboardAnimationData?
public let content: ItemContent
public let itemFile: TelegramMediaFile?
public let itemFile: TelegramMediaFile.Accessor?
public let itemGift: StarGift.UniqueGift?
public let subgroupId: Int32?
public let icon: Icon
@ -410,7 +424,7 @@ public final class EmojiPagerContentComponent: Component {
public init(
animationData: EntityKeyboardAnimationData?,
content: ItemContent,
itemFile: TelegramMediaFile?,
itemFile: TelegramMediaFile.Accessor?,
itemGift: StarGift.UniqueGift? = nil,
subgroupId: Int32?,
icon: Icon,
@ -429,7 +443,7 @@ public final class EmojiPagerContentComponent: Component {
if lhs === rhs {
return true
}
if lhs.animationData?.resource.resource.id != rhs.animationData?.resource.resource.id {
if lhs.animationData?.resource != rhs.animationData?.resource {
return false
}
if lhs.content != rhs.content {
@ -1723,7 +1737,7 @@ public final class EmojiPagerContentComponent: Component {
})
}
component.animationRenderer.setFrameIndex(itemId: animationData.resource.resource.id.stringRepresentation, size: itemLayer.pixelSize, frameIndex: sourceItem.frameIndex, placeholder: sourceItem.placeholder)
component.animationRenderer.setFrameIndex(itemId: animationData.resource._parse().resource.id.stringRepresentation, size: itemLayer.pixelSize, frameIndex: sourceItem.frameIndex, placeholder: sourceItem.placeholder)
} else {
let distance = itemLayer.position.y - itemLayout.frame(groupIndex: 0, itemIndex: 0).midY
let maxDistance = self.bounds.height
@ -4126,7 +4140,7 @@ public final class EmojiPagerContentComponent: Component {
if itemLayer.displayPlaceholder {
return nil
}
return (item.1.groupId, itemLayer, file)
return (item.1.groupId, itemLayer, file._parse())
})
let keyboardChildEnvironment = environment[EntityKeyboardChildEnvironment.self].value

View File

@ -134,7 +134,7 @@ public extension EmojiPagerContentComponent {
|> map { result -> [TelegramMediaFile] in
switch result {
case let .result(_, items, _):
return items.map(\.file)
return items.map({ $0.file._parse() })
default:
return []
}
@ -148,7 +148,7 @@ public extension EmojiPagerContentComponent {
|> map { result -> [TelegramMediaFile] in
switch result {
case let .result(_, items, _):
return items.map(\.file)
return items.map({ $0.file._parse() })
default:
return []
}
@ -164,7 +164,7 @@ public extension EmojiPagerContentComponent {
|> map { result -> [TelegramMediaFile] in
switch result {
case let .result(_, items, _):
return items.map(\.file)
return items.map({ $0.file._parse() })
default:
return []
}
@ -198,6 +198,11 @@ public extension EmojiPagerContentComponent {
searchCategories = .single(nil)
}
#if DEBUG || true
var isFirstTime = true
let measure_startTime = CFAbsoluteTimeGetCurrent()
#endif
let emojiItems: Signal<EmojiPagerContentComponent, NoError> = combineLatest(
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: orderedItemListCollectionIds, namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
forceHasPremium ? .single(true) : hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: premiumIfSavedMessages),
@ -209,6 +214,52 @@ public extension EmojiPagerContentComponent {
ApplicationSpecificNotice.dismissedTrendingEmojiPacks(accountManager: context.sharedContext.accountManager)
)
|> map { view, hasPremium, featuredEmojiPacks, availableReactions, searchCategories, iconStatusEmoji, peerSpecificPack, dismissedTrendingEmojiPacks -> EmojiPagerContentComponent in
#if DEBUG || true
if isFirstTime {
var files: [TelegramMediaFile] = []
files.removeAll()
if "".isEmpty {
for entry in view.entries {
guard let item = entry.item as? StickerPackItem else {
continue
}
files.append(item.file._parse())
}
for featuredEmojiPack in featuredEmojiPacks {
for item in featuredEmojiPack.topItems {
files.append(item.file._parse())
}
}
if let availableReactions {
for reactionItem in availableReactions.reactions {
files.append(reactionItem.staticIcon._parse())
files.append(reactionItem.appearAnimation._parse())
files.append(reactionItem.selectAnimation._parse())
files.append(reactionItem.activateAnimation._parse())
files.append(reactionItem.effectAnimation._parse())
if let aroundAnimation = reactionItem.aroundAnimation {
files.append(aroundAnimation._parse())
}
if let centerAnimation = reactionItem.centerAnimation {
files.append(centerAnimation._parse())
}
}
}
Thread.current.threadDictionary["afwefw"] = files
}
isFirstTime = false
let measuredTime = CFAbsoluteTimeGetCurrent() - measure_startTime
for file in files {
if file.fileId.id == 123 {
print("Interesting")
}
}
print("emojiInputData init isMainThread: \(Thread.isMainThread): \(measuredTime * 1000.0) ms")
}
#endif
struct ItemGroup {
var supergroupId: AnyHashable
var id: AnyHashable
@ -295,7 +346,7 @@ public extension EmojiPagerContentComponent {
animationData = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(featuredEmojiPack.info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: featuredEmojiPack.info.id.id, accessHash: featuredEmojiPack.info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: featuredEmojiPack.info.id.id, accessHash: featuredEmojiPack.info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: featuredEmojiPack.info.immediateThumbnailData,
isReaction: false,
@ -440,11 +491,11 @@ public extension EmojiPagerContentComponent {
let resultItem: EmojiPagerContentComponent.Item
let animationData = EntityKeyboardAnimationData(file: file)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(file))
resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: file,
itemFile: TelegramMediaFile.Accessor(file),
subgroupId: nil,
icon: .none,
tintMode: tintMode
@ -499,11 +550,11 @@ public extension EmojiPagerContentComponent {
let resultItem: EmojiPagerContentComponent.Item
let animationData = EntityKeyboardAnimationData(file: file)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(file))
resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: file,
itemFile: TelegramMediaFile.Accessor(file),
subgroupId: nil,
icon: .none,
tintMode: tintMode
@ -530,17 +581,8 @@ public extension EmojiPagerContentComponent {
if file.isCustomTemplateEmoji {
tintMode = .accent
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
if file.internal_isHardcodedTemplateEmoji {
tintMode = .accent
}
let resultItem: EmojiPagerContentComponent.Item
@ -582,17 +624,8 @@ public extension EmojiPagerContentComponent {
if file.isCustomTemplateEmoji {
tintMode = .accent
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
if file.internal_isHardcodedTemplateEmoji {
tintMode = .accent
}
let animationData = EntityKeyboardAnimationData(file: file)
@ -700,11 +733,11 @@ public extension EmojiPagerContentComponent {
let resultItem: EmojiPagerContentComponent.Item
let animationData = EntityKeyboardAnimationData(file: file)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(file))
resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: file,
itemFile: TelegramMediaFile.Accessor(file),
subgroupId: nil,
icon: .none,
tintMode: tintMode
@ -733,17 +766,8 @@ public extension EmojiPagerContentComponent {
if file.isCustomTemplateEmoji {
tintMode = .accent
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
if file.internal_isHardcodedTemplateEmoji {
tintMode = .accent
}
let animationData = EntityKeyboardAnimationData(file: file)
@ -757,10 +781,6 @@ public extension EmojiPagerContentComponent {
)
if let groupIndex = itemGroupIndexById[groupId] {
/*if itemGroups[groupIndex].items.count >= (5 + 8) * 8 {
break
}*/
itemGroups[groupIndex].items.append(resultItem)
}
}
@ -971,7 +991,7 @@ public extension EmojiPagerContentComponent {
continue
}
let animationFile: TelegramMediaFile
let animationFile: TelegramMediaFile.Accessor
let icon: EmojiPagerContentComponent.Item.Icon
switch item.content {
@ -1145,17 +1165,8 @@ public extension EmojiPagerContentComponent {
if file.isCustomTemplateEmoji {
tintMode = .accent
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
if file.internal_isHardcodedTemplateEmoji {
tintMode = .accent
}
let animationData = EntityKeyboardAnimationData(file: file)
@ -1219,17 +1230,8 @@ public extension EmojiPagerContentComponent {
tintMode = .accent
}
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
if file.internal_isHardcodedTemplateEmoji {
tintMode = .accent
}
let animationData = EntityKeyboardAnimationData(file: file)
@ -1277,11 +1279,11 @@ public extension EmojiPagerContentComponent {
tintMode = .primary
}
let animationData = EntityKeyboardAnimationData(file: file)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(file))
resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: file,
itemFile: TelegramMediaFile.Accessor(file),
subgroupId: nil,
icon: .none,
tintMode: tintMode
@ -1368,14 +1370,6 @@ public extension EmojiPagerContentComponent {
continue
}
#if DEBUG && false
let fbData = item.file.encodeToFlatBuffersData()
var byteBuffer = ByteBuffer(data: fbData)
let flatBuffersObject: TelegramCore_TelegramMediaFile = try! getCheckedRoot(byteBuffer: &byteBuffer)
let fbObject = try! TelegramMediaFile(flatBuffersObject: flatBuffersObject)
assert(item.file == fbObject)
#endif
var icon: EmojiPagerContentComponent.Item.Icon = .none
if [.reaction(onlyTop: false), .quickReaction].contains(subject), !hasPremium {
icon = .locked
@ -1455,7 +1449,7 @@ public extension EmojiPagerContentComponent {
headerItem = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: info.immediateThumbnailData,
isReaction: false,
@ -1542,7 +1536,7 @@ public extension EmojiPagerContentComponent {
headerItem = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: info.immediateThumbnailData,
isReaction: false,
@ -1839,7 +1833,7 @@ public extension EmojiPagerContentComponent {
animationData = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(featuredStickerPack.info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: featuredStickerPack.info.immediateThumbnailData,
isReaction: false,
@ -2076,7 +2070,7 @@ public extension EmojiPagerContentComponent {
headerItem = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: info.immediateThumbnailData,
isReaction: false,
@ -2155,7 +2149,7 @@ public extension EmojiPagerContentComponent {
headerItem = EntityKeyboardAnimationData(
id: .stickerPackThumbnail(info.id),
type: type,
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)),
dimensions: thumbnail.dimensions.cgSize,
immediateThumbnailData: info.immediateThumbnailData,
isReaction: false,
@ -2315,11 +2309,11 @@ public extension EmojiPagerContentComponent {
}
}
let animationData = EntityKeyboardAnimationData(file: itemFile, partialReference: .none)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile), partialReference: .none)
let resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: icon,
tintMode: tintMode

View File

@ -234,7 +234,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
)
|> take(1)
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var result: [(String, TelegramMediaFile.Accessor?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
@ -247,18 +247,16 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if item.file.isCustomEmoji {
if !item.file.isPremiumEmoji || hasPremium {
if let alt = item.file.customEmojiAlt {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
}
default:
break
}
}
}
@ -329,11 +327,11 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none

View File

@ -200,7 +200,7 @@ public final class GifContext {
var items: [GifPagerContentComponent.Item] = []
for gifItem in savedGifs {
items.append(GifPagerContentComponent.Item(
file: .savedGif(media: gifItem.contents.get(RecentMediaItem.self)!.media),
file: .savedGif(media: gifItem.contents.get(RecentMediaItem.self)!.media._parse()),
contextResult: nil
))
}

View File

@ -267,7 +267,7 @@ class GroupStickerPackCurrentItemNode: ItemListRevealOptionsItemNode {
var file: TelegramMediaFile?
var previousFile: TelegramMediaFile?
if let currentItem = currentItem, case let .found(_, topItem, _) = currentItem.content {
previousFile = topItem?.file
previousFile = topItem?.file._parse()
}
switch item.content {
@ -278,7 +278,7 @@ class GroupStickerPackCurrentItemNode: ItemListRevealOptionsItemNode {
titleAttributedString = NSAttributedString(string: item.strings.Channel_Stickers_Searching, font: titleFont, textColor: item.theme.list.itemPrimaryTextColor)
statusAttributedString = NSAttributedString(string: "", font: statusFont, textColor: item.theme.list.itemSecondaryTextColor)
case let .found(packInfo, topItem, subtitle):
file = topItem?.file
file = topItem?.file._parse()
titleAttributedString = NSAttributedString(string: packInfo.title, font: titleFont, textColor: item.theme.list.itemPrimaryTextColor)
statusAttributedString = NSAttributedString(string: subtitle, font: statusFont, textColor: item.theme.list.itemSecondaryTextColor)
}

View File

@ -4703,11 +4703,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|> map { result -> TelegramMediaFile? in
if case let .result(_, items, _) = result, let match = items.first(where: { item in
var displayText: String?
for attribute in item.file.attributes {
if case let .CustomEmoji(_, _, alt, _) = attribute {
displayText = alt
break
}
if let alt = item.file.customEmojiAlt {
displayText = alt
}
if let displayText, displayText.hasPrefix(flag) {
return true
@ -4715,7 +4712,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
return false
}
}) {
return match.file
return match.file._parse()
} else {
return nil
}
@ -5113,7 +5110,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
if let reaction = self.availableReactions.first(where: { reaction in
return reaction.reaction.rawValue == .builtin(heart)
}) {
let stickerEntity = DrawingStickerEntity(content: .file(.standalone(media: reaction.stillAnimation), .reaction(.builtin(heart), .white)))
let stickerEntity = DrawingStickerEntity(content: .file(.standalone(media: reaction.stillAnimation._parse()), .reaction(.builtin(heart), .white)))
self.interaction?.insertEntity(stickerEntity, scale: 1.175)
}

View File

@ -53,14 +53,15 @@ private final class StickerPackListContextItemNode: ASDisplayNode, ContextMenuCu
continue
}
let thumbSize = CGSize(width: 24.0, height: 24.0)
let thumbnailResource = pack.thumbnail?.resource ?? topItem?.file.resource
let topItemFile = topItem?.file._parse()
let thumbnailResource = pack.thumbnail?.resource ?? topItemFile?.resource
let thumbnailIconSource: ContextMenuActionItemIconSource?
if let thumbnailResource {
var resourceId: Int64 = 0
if let resource = thumbnailResource as? CloudDocumentMediaResource {
resourceId = resource.fileId
}
let thumbnailFile = topItem?.file ?? TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: resourceId), partialReference: nil, resource: thumbnailResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: thumbnailResource.size ?? 0, attributes: [], alternativeRepresentations: [])
let thumbnailFile = topItemFile ?? TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: resourceId), partialReference: nil, resource: thumbnailResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: thumbnailResource.size ?? 0, attributes: [], alternativeRepresentations: [])
let _ = freeMediaFileInteractiveFetched(account: item.context.account, userLocation: .other, fileReference: .stickerPack(stickerPack: .id(id: pack.id.id, accessHash: pack.accessHash), media: thumbnailFile)).start()
thumbnailIconSource = ContextMenuActionItemIconSource(

View File

@ -73,7 +73,7 @@ func getWeather(context: AccountContext, load: Bool) -> Signal<StickerPickerScre
if let match = context.animatedEmojiStickersValue[effectiveEmoji]?.first {
return .single(.loaded(StickerPickerScreen.Weather.LoadedWeather(
emoji: effectiveEmoji,
emojiFile: match.file,
emojiFile: match.file._parse(),
temperature: weather.temperature
)))
} else {

View File

@ -263,7 +263,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, cha
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
for stringRepresentation in stringRepresentations {
if stringRepresentation == query {
result.append((stringRepresentation, item.file, stringRepresentation))
result.append((stringRepresentation, item.file._parse(), stringRepresentation))
break
}
}
@ -313,7 +313,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, cha
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
for stringRepresentation in stringRepresentations {
if let keyword = allEmoticons[stringRepresentation] {
result.append((stringRepresentation, item.file, keyword))
result.append((stringRepresentation, item.file._parse(), keyword))
break
}
}

View File

@ -8,6 +8,7 @@ import SwitchComponent
import EntityKeyboard
import AccountContext
import HierarchyTrackingLayer
import TelegramCore
private final class CaretIndicatorView: UIImageView {
private let hierarchyTrackingLayer: HierarchyTrackingLayer

View File

@ -542,7 +542,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
}
let text = presentationData.strings.ChannelReactions_ToastLevelBoostRequiredTemplate(presentationData.strings.ChannelReactions_ToastLevelBoostRequiredTemplateLevel(Int32(nextCustomReactionCount)), presentationData.strings.ChannelReactions_ToastLevelBoostRequiredTemplateEmojiCount(Int32(nextCustomReactionCount))).string
let undoController = UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: component.context, file: itemFile, loop: false, title: nil, text: text, undoText: nil, customAction: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
let undoController = UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: component.context, file: itemFile._parse(), loop: false, title: nil, text: text, undoText: nil, customAction: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
self.currentUndoController = undoController
self.environment?.controller()?.present(undoController, in: .current)
}
@ -698,7 +698,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
localPacksSignal
)
|> map { view, availableReactions, hasPremium, foundPacks, foundEmoji, foundLocalPacks -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var result: [(String, TelegramMediaFile.Accessor?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
@ -712,9 +712,9 @@ final class PeerAllowedReactionsScreenComponent: Component {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, itemFile, keyword))
result.append((alt, TelegramMediaFile.Accessor(itemFile), keyword))
} else if alt == query {
result.append((alt, itemFile, alt))
result.append((alt, TelegramMediaFile.Accessor(itemFile), alt))
}
default:
break
@ -726,18 +726,13 @@ final class PeerAllowedReactionsScreenComponent: Component {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
if !item.file.isPremiumEmoji {
if let alt = item.file.customEmojiAlt {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
default:
break
}
}
}
@ -877,11 +872,12 @@ final class PeerAllowedReactionsScreenComponent: Component {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -1855,7 +1851,7 @@ public class PeerAllowedReactionsScreen: ViewControllerComponentContainer {
} else {
if case let .custom(fileId) = reaction {
if let file = files[fileId] {
result.append(EmojiComponentReactionItem(reaction: reaction, file: file))
result.append(EmojiComponentReactionItem(reaction: reaction, file: TelegramMediaFile.Accessor(file)))
}
}
}

View File

@ -616,7 +616,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
var file: TelegramMediaFile?
switch leftIcon {
case .birthday:
file = context.animatedEmojiStickersValue["🎂"]?.first?.file
file = context.animatedEmojiStickersValue["🎂"]?.first?.file._parse()
}
if let file {

View File

@ -45,11 +45,11 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
var effectFile: FileMediaReference?
if case let .result(_, items, _) = animatedEmoji {
let randomKey = ["🎉", "🎈", "🎆"].randomElement()!
outer: for item in items {
outer: for item in items {
let indexKeys = item.getStringRepresentationsOfIndexKeys()
for key in indexKeys {
if key == randomKey {
effectFile = .stickerPack(stickerPack: .animatedEmojiAnimations, media: item.file)
effectFile = .stickerPack(stickerPack: .animatedEmojiAnimations, media: item.file._parse())
break outer
}
}
@ -63,7 +63,7 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
let indexKeys = item.getStringRepresentationsOfIndexKeys()
for key in indexKeys {
if key == ageKey {
numberFiles.append(.stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file))
numberFiles.append(.stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file._parse()))
}
}
}
@ -185,7 +185,7 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
let indexKeys = item.getStringRepresentationsOfIndexKeys()
for key in indexKeys {
if ["🎉", "🎈", "🎆"].contains(key) {
signals.append(freeMediaFileInteractiveFetched(account: context.account, userLocation: .peer(context.account.peerId), fileReference: .stickerPack(stickerPack: .animatedEmojiAnimations, media: item.file)))
signals.append(freeMediaFileInteractiveFetched(account: context.account, userLocation: .peer(context.account.peerId), fileReference: .stickerPack(stickerPack: .animatedEmojiAnimations, media: item.file._parse())))
}
}
}
@ -196,7 +196,7 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
let indexKeys = item.getStringRepresentationsOfIndexKeys()
for key in indexKeys {
if ageKeys.contains(key) {
signals.append(freeMediaFileInteractiveFetched(account: context.account, userLocation: .peer(context.account.peerId), fileReference: .stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file)))
signals.append(freeMediaFileInteractiveFetched(account: context.account, userLocation: .peer(context.account.peerId), fileReference: .stickerPack(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), media: item.file._parse())))
}
}
}

View File

@ -952,7 +952,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
}
|> mapToSignal { result -> Signal<(TelegramMediaFile, LoadedStickerPack)?, NoError> in
if case let .result(_, items, _) = result {
return .single(items.first.flatMap { ($0.file, result) })
return .single(items.first.flatMap { ($0.file._parse(), result) })
} else {
return .complete()
}

View File

@ -306,7 +306,7 @@ final class BusinessIntroSetupScreenComponent: Component {
return
}
self.stickerFile = itemFile
self.stickerFile = itemFile._parse()
self.displayStickerInput = false
self.stickerSearchDisposable.set(nil)
@ -490,11 +490,11 @@ final class BusinessIntroSetupScreenComponent: Component {
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
@ -581,11 +581,12 @@ final class BusinessIntroSetupScreenComponent: Component {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: itemFile.isPremiumSticker ? .premium : .none,
tintMode: animationData.isTemplate ? .primary : .none
)

View File

@ -331,7 +331,7 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
if let availableReactions = item.availableReactions {
for reaction in availableReactions.reactions {
if reaction.value == item.reaction {
animationContent = .file(file: reaction.selectAnimation)
animationContent = .file(file: reaction.selectAnimation._parse())
break
}
}
@ -342,7 +342,7 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
if let availableReactions = item.availableReactions {
for reaction in availableReactions.reactions {
if reaction.value == item.reaction {
animationContent = .file(file: reaction.selectAnimation)
animationContent = .file(file: reaction.selectAnimation._parse())
break
}
}

View File

@ -194,6 +194,7 @@ class ReactionChatPreviewItemNode: ListViewItemNode {
return
}
if let itemFile = files[fileId] {
let itemFile = TelegramMediaFile.Accessor(itemFile)
let reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: .custom(itemFile.fileId.id)),
appearAnimation: itemFile,

View File

@ -875,7 +875,7 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
hasCurrentTheme = true
}
let emojiFile = theme.emoticon.flatMap { item.animatedEmojiStickers[$0]?.first?.file }
entries.append(ThemeCarouselThemeEntry(index: index, emojiFile: emojiFile, themeReference: theme, nightMode: item.nightMode, channelMode: item.channelMode, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil))
entries.append(ThemeCarouselThemeEntry(index: index, emojiFile: emojiFile?._parse(), themeReference: theme, nightMode: item.nightMode, channelMode: item.channelMode, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil))
index += 1
}

View File

@ -418,7 +418,7 @@ final class ThemeGridControllerNode: ASDisplayNode {
if let selectedWallpaper, !selectedWallpaper.isEmoticon {
entries.append(ThemeGridControllerEntry(index: index, theme: presentationData.theme, wallpaper: selectedWallpaper, channelMode: true, isEditable: false, isSelected: true))
} else {
let emojiFile = context.animatedEmojiStickersValue[""]?.first?.file
let emojiFile = context.animatedEmojiStickersValue[""]?.first?.file._parse()
entries.append(ThemeGridControllerEntry(index: index, theme: presentationData.theme, wallpaper: .color(0), isEmpty: true, emoji: emojiFile, channelMode: true, isEditable: false, isSelected: selectedWallpaper == nil))
}
index += 1
@ -441,7 +441,7 @@ final class ThemeGridControllerNode: ASDisplayNode {
}
let emoji = context.animatedEmojiStickersValue[themeEmoticon]
entries.append(ThemeGridControllerEntry(index: index, theme: presentationData.theme, wallpaper: updatedWallpaper, emoji: emoji?.first?.file, channelMode: true, isEditable: false, isSelected: isSelected))
entries.append(ThemeGridControllerEntry(index: index, theme: presentationData.theme, wallpaper: updatedWallpaper, emoji: emoji?.first?.file._parse(), channelMode: true, isEditable: false, isSelected: isSelected))
index += 1
}
} else {

View File

@ -896,7 +896,7 @@ public class StickerPickerScreen: ViewController {
}
})
})
} else if let file = item.itemFile {
} else if let file = item.itemFile?._parse() {
if controller.completion(.file(.standalone(media: file), .sticker)) {
controller.dismiss(animated: true)
}
@ -1119,11 +1119,11 @@ public class StickerPickerScreen: ViewController {
if itemFile.isPremiumEmoji && !hasPremium {
continue
}
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
@ -1180,11 +1180,12 @@ public class StickerPickerScreen: ViewController {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -1289,7 +1290,7 @@ public class StickerPickerScreen: ViewController {
content.stickers?.inputInteractionHolder.inputInteraction = EmojiPagerContentComponent.InputInteraction(
performItemAction: { [weak self] groupId, item, _, _, _, _ in
guard let self, let controller = self.controller, let file = item.itemFile else {
guard let self, let controller = self.controller, let file = item.itemFile?._parse() else {
return
}
let presentationData = controller.context.sharedContext.currentPresentationData.with { $0 }
@ -1467,11 +1468,12 @@ public class StickerPickerScreen: ViewController {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let animationData = EntityKeyboardAnimationData(file: TelegramMediaFile.Accessor(itemFile))
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
itemFile: TelegramMediaFile.Accessor(itemFile),
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
@ -2733,7 +2735,7 @@ final class StoryStickersContentView: UIView, EmojiCustomContentView {
theme: theme,
title: stringForTemperature(24),
iconName: "☀️",
iconFile: self.context.animatedEmojiStickersValue["☀️"]?.first?.file,
iconFile: self.context.animatedEmojiStickersValue["☀️"]?.first?.file._parse(),
useOpaqueTheme: useOpaqueTheme,
tintContainerView: self.tintContainerView
)

View File

@ -1876,7 +1876,7 @@ public func preloadStoryMedia(context: AccountContext, info: StoryPreloadInfo) -
for reaction in availableReactions.reactions {
for value in builtinReactions {
if case .builtin(value) = reaction.value {
files.append(reaction.selectAnimation)
files.append(reaction.selectAnimation._parse())
}
}
}
@ -2110,7 +2110,7 @@ public func waitUntilStoryMediaPreloaded(context: AccountContext, peerId: Engine
for reaction in availableReactions.reactions {
for value in builtinReactions {
if case .builtin(value) = reaction.value {
files.append(reaction.selectAnimation)
files.append(reaction.selectAnimation._parse())
}
}
}

View File

@ -89,7 +89,7 @@ public func storyPreviewWithAddedReactions(
guard let file = item.centerAnimation else {
break
}
return loadFile(reaction, file)
return loadFile(reaction, file._parse())
}
}
return .single((reaction, nil))
@ -339,7 +339,7 @@ final class StoryItemOverlaysView: UIView {
if let availableReactions {
for reactionItem in availableReactions.reactionItems {
if reactionItem.reaction.rawValue == reaction {
file = reactionItem.stillAnimation
file = reactionItem.stillAnimation._parse()
break
}
}
@ -367,7 +367,7 @@ final class StoryItemOverlaysView: UIView {
if let availableReactions {
for reactionItem in availableReactions.reactionItems {
if reactionItem.reaction.rawValue == reaction {
file = reactionItem.stillAnimation
file = reactionItem.stillAnimation._parse()
break
}
}
@ -790,7 +790,7 @@ final class StoryItemOverlaysView: UIView {
let itemSize = itemView.update(
context: context,
emoji: emoji,
emojiFile: context.animatedEmojiStickersValue[emoji]?.first?.file,
emojiFile: context.animatedEmojiStickersValue[emoji]?.first?.file._parse(),
temperature: temperature,
color: color,
synchronous: attemptSynchronous,

View File

@ -1738,7 +1738,7 @@ public final class StoryItemSetContainerComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == value {
centerAnimation = availableReaction.listAnimation
centerAnimation = availableReaction.listAnimation._parse()
break
}
}
@ -1749,7 +1749,7 @@ public final class StoryItemSetContainerComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == value {
centerAnimation = availableReaction.listAnimation
centerAnimation = availableReaction.listAnimation._parse()
break
}
}
@ -2951,7 +2951,7 @@ public final class StoryItemSetContainerComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == value {
centerAnimation = availableReaction.listAnimation
centerAnimation = availableReaction.listAnimation._parse()
break
}
}
@ -2962,7 +2962,7 @@ public final class StoryItemSetContainerComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == value {
centerAnimation = availableReaction.listAnimation
centerAnimation = availableReaction.listAnimation._parse()
break
}
}
@ -4582,7 +4582,7 @@ public final class StoryItemSetContainerComponent: Component {
var animation: TelegramMediaFile?
for reaction in availableReactions.reactions {
if reaction.value == updateReaction.reaction {
animation = reaction.centerAnimation
animation = reaction.centerAnimation?._parse()
break
}
}
@ -5989,7 +5989,7 @@ public final class StoryItemSetContainerComponent: Component {
placeholderColor: .clear,
attemptSynchronous: true
),
file: items.first?.file,
file: items.first?.file._parse(),
action: action)
return .single(tip)
} else {

View File

@ -3569,6 +3569,7 @@ final class StoryItemSetContainerSendMessage {
let _ = (component.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])
|> deliverOnMainQueue).start(next: { files in
if let itemFile = files[fileId] {
let itemFile = TelegramMediaFile.Accessor(itemFile)
let reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: .custom(itemFile.fileId.id)),
appearAnimation: itemFile,

View File

@ -559,7 +559,7 @@ final class StoryItemSetViewListComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == reaction {
animationFile = availableReaction.listAnimation
animationFile = availableReaction.listAnimation._parse()
break
}
}
@ -573,7 +573,7 @@ final class StoryItemSetViewListComponent: Component {
if let availableReactions = component.availableReactions {
for availableReaction in availableReactions.reactionItems {
if availableReaction.reaction.rawValue == reaction {
animationFile = availableReaction.listAnimation
animationFile = availableReaction.listAnimation._parse()
break
}
}

View File

@ -1750,6 +1750,7 @@ extension ChatControllerImpl {
}
case let .custom(fileId):
if let itemFile = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile {
let itemFile = TelegramMediaFile.Accessor(itemFile)
reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: updatedReaction),
appearAnimation: itemFile,

View File

@ -276,7 +276,7 @@ extension ChatControllerImpl {
placeholderColor: .clear,
attemptSynchronous: true
),
file: items.first?.file,
file: items.first?.file._parse(),
action: action)
return .single(actions)
} else {

View File

@ -1692,6 +1692,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
case let .custom(fileId):
if let itemFile = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile {
let itemFile = TelegramMediaFile.Accessor(itemFile)
reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: chosenReaction),
appearAnimation: itemFile,
@ -1879,6 +1880,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
case let .custom(fileId):
if let itemFile = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile {
let itemFile = TelegramMediaFile.Accessor(itemFile)
reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: chosenReaction),
appearAnimation: itemFile,
@ -4424,7 +4426,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|> take(1)
|> mapToSignal { result -> Signal<PremiumSource, NoError> in
if case let .result(_, items, _) = result {
return .single(.emojiStatus(peerId, peerStatus, items.first?.file, result))
return .single(.emojiStatus(peerId, peerStatus, items.first?.file._parse(), result))
} else {
return .single(.emojiStatus(peerId, peerStatus, nil, nil))
}

View File

@ -48,7 +48,7 @@ extension ChatControllerImpl {
reactionFile = self.context.engine.stickers.availableReactions()
|> take(1)
|> map { availableReactions -> TelegramMediaFile? in
return availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation
return availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation._parse()
}
case let .custom(fileId):
reactionFile = self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])
@ -325,7 +325,7 @@ extension ChatControllerImpl {
placeholderColor: .clear,
attemptSynchronous: true
),
file: items.first?.file,
file: items.first?.file._parse(),
action: action)
return .single(tip)
} else {
@ -338,7 +338,7 @@ extension ChatControllerImpl {
let reactionFile: TelegramMediaFile?
switch value {
case .builtin, .stars:
reactionFile = availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation
reactionFile = availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation._parse()
case let .custom(fileId):
reactionFile = customEmoji[fileId]
}

View File

@ -4188,6 +4188,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
case let .custom(fileId):
if let itemFile = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile {
let itemFile = TelegramMediaFile.Accessor(itemFile)
reactionItem = ReactionItem(
reaction: ReactionItem.Reaction(rawValue: updatedReaction),
appearAnimation: itemFile,

View File

@ -388,7 +388,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
for stringRepresentation in stringRepresentations {
if stringRepresentation == query {
result.append((stringRepresentation, item.file, stringRepresentation))
result.append((stringRepresentation, item.file._parse(), stringRepresentation))
break
}
}
@ -438,7 +438,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
let stringRepresentations = item.getStringRepresentationsOfIndexKeys()
for stringRepresentation in stringRepresentations {
if let keyword = allEmoticons[stringRepresentation] {
result.append((stringRepresentation, item.file, keyword))
result.append((stringRepresentation, item.file._parse(), keyword))
break
}
}

View File

@ -517,7 +517,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
inner: for availableReaction in availableReactions.reactions {
if availableReaction.value == reaction {
if let file = availableReaction.centerAnimation {
self.items.append(Item(reaction: reaction, count: count, title: title, file: file))
self.items.append(Item(reaction: reaction, count: count, title: title, file: file._parse()))
}
break inner
}
@ -769,7 +769,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
reactionFile = self.context.engine.stickers.availableReactions()
|> take(1)
|> map { availableReactions -> TelegramMediaFile? in
return availableReactions?.reactions.first(where: { $0.value == reaction })?.selectAnimation
return availableReactions?.reactions.first(where: { $0.value == reaction })?.selectAnimation._parse()
}
case let .custom(fileId):
reactionFile = self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])

View File

@ -893,7 +893,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, ASScrollViewDelega
guard let emoticon = theme.emoticon else {
continue
}
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file, themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon?.strippedEmoji, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file._parse(), themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon?.strippedEmoji, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
}
let action: (String?) -> Void = { [weak self] emoticon in

View File

@ -179,18 +179,18 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
.action(ContextMenuActionItem(text: strongSelf.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, false, nil, true, itemNode.view, itemNode.bounds, nil, [])
let _ = controllerInteraction.sendSticker(.standalone(media: item.file._parse()), false, false, nil, true, itemNode.view, itemNode.bounds, nil, [])
})),
.action(ContextMenuActionItem(text: isStarred ? strongSelf.strings.Stickers_RemoveFromFavorites : strongSelf.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: isStarred ? UIImage(bundleImageName: "Chat/Context Menu/Unfave") : UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
f(.default)
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file._parse(), saved: !isStarred)
|> deliverOnMainQueue).startStandalone(next: { result in
switch result {
case .generic:
strongSelf.interfaceInteraction?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
strongSelf.interfaceInteraction?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
case let .limitExceeded(limit, premiumLimit):
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: strongSelf.context.currentAppConfiguration.with { $0 })
let text: String
@ -199,7 +199,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
} else {
text = strongSelf.strings.Premium_MaxFavedStickersText("\(premiumLimit)").string
}
strongSelf.interfaceInteraction?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: strongSelf.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
strongSelf.interfaceInteraction?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: strongSelf.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
if let strongSelf = self {
if case .info = action {
let controller = PremiumIntroScreen(context: strongSelf.context, source: .savedStickers)
@ -217,7 +217,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
f(.default)
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
loop: for attribute in item.file.attributes {
loop: for attribute in item.file._parse().attributes {
switch attribute {
case let .Sticker(_, packReference, _):
if let packReference = packReference {
@ -240,7 +240,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
}
}))
]
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.theme, strings: strongSelf.strings, item: .pack(item.file), menu: menuItems, openPremiumIntro: { [weak self] in
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.theme, strings: strongSelf.strings, item: .pack(item.file._parse()), menu: menuItems, openPremiumIntro: { [weak self] in
guard let strongSelf = self else {
return
}

View File

@ -114,9 +114,9 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, animationNode.view, animationNode.bounds, nil, [])
let _ = controllerInteraction.sendSticker(.standalone(media: item.file._parse()), true, false, nil, true, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, imageNode.view, imageNode.bounds, nil, [])
let _ = controllerInteraction.sendSticker(.standalone(media: item.file._parse()), true, false, nil, true, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -128,9 +128,9 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, animationNode.view, animationNode.bounds, nil, [])
let _ = controllerInteraction.sendSticker(.standalone(media: item.file._parse()), false, true, nil, true, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, imageNode.view, imageNode.bounds, nil, [])
let _ = controllerInteraction.sendSticker(.standalone(media: item.file._parse()), false, true, nil, true, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -142,11 +142,11 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file, saved: !isStarred)
let _ = (strongSelf.context.engine.stickers.toggleStickerSaved(file: item.file._parse(), saved: !isStarred)
|> deliverOnMainQueue).startStandalone(next: { result in
switch result {
case .generic:
strongSelf.getControllerInteraction?()?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
strongSelf.getControllerInteraction?()?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: nil, text: !isStarred ? strongSelf.strings.Conversation_StickerAddedToFavorites : strongSelf.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
case let .limitExceeded(limit, premiumLimit):
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: strongSelf.context.currentAppConfiguration.with { $0 })
let text: String
@ -155,7 +155,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
} else {
text = strongSelf.strings.Premium_MaxFavedStickersText("\(premiumLimit)").string
}
strongSelf.getControllerInteraction?()?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file, loop: true, title: strongSelf.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
strongSelf.getControllerInteraction?()?.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: strongSelf.context, file: item.file._parse(), loop: true, title: strongSelf.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { [weak self] action in
if let strongSelf = self {
if case .info = action {
let controller = PremiumIntroScreen(context: strongSelf.context, source: .savedStickers)
@ -176,7 +176,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
f(.default)
if let strongSelf = self, let controllerInteraction = strongSelf.getControllerInteraction?() {
loop: for attribute in item.file.attributes {
loop: for attribute in item.file._parse().attributes {
switch attribute {
case let .Sticker(_, packReference, _):
if let packReference = packReference {
@ -199,7 +199,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, ASScrollVie
}
}))
)
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.theme, strings: strongSelf.strings, item: .pack(item.file), menu: menuItems, openPremiumIntro: { [weak self] in
return (itemNode.view, itemNode.bounds, StickerPreviewPeekContent(context: strongSelf.context, theme: strongSelf.theme, strings: strongSelf.strings, item: .pack(item.file._parse()), menu: menuItems, openPremiumIntro: { [weak self] in
guard let strongSelf = self, let controllerInteraction = strongSelf.getControllerInteraction?() else {
return
}

View File

@ -75,9 +75,10 @@ private final class PrefetchManagerInnerImpl {
let popularEmoji = ["\u{2764}", "👍", "👎", "😳", "😒", "🥳", "😡", "😮", "😂", "😘", "😍", "🙄", "😎"]
for emoji in popularEmoji {
if let sticker = animatedEmojiStickers[emoji] {
if let _ = account.postbox.mediaBox.completedResourcePath(sticker.file.resource) {
let stickerFile = sticker.file._parse()
if let _ = account.postbox.mediaBox.completedResourcePath(stickerFile.resource) {
} else {
stickerItems.append(.animatedEmojiSticker(sticker.file))
stickerItems.append(.animatedEmojiSticker(stickerFile))
}
}
}

View File

@ -62,7 +62,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
public var dynamicStreaming: Bool
public var enableLocalTranslation: Bool
public var autoBenchmarkReflectors: Bool?
public var conferenceCalls: Bool
public var playerV2: Bool
public var devRequests: Bool
public var fakeAds: Bool
@ -106,7 +105,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
dynamicStreaming: false,
enableLocalTranslation: false,
autoBenchmarkReflectors: nil,
conferenceCalls: false,
playerV2: false,
devRequests: false,
fakeAds: false
@ -151,7 +149,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
dynamicStreaming: Bool,
enableLocalTranslation: Bool,
autoBenchmarkReflectors: Bool?,
conferenceCalls: Bool,
playerV2: Bool,
devRequests: Bool,
fakeAds: Bool
@ -193,7 +190,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
self.dynamicStreaming = dynamicStreaming
self.enableLocalTranslation = enableLocalTranslation
self.autoBenchmarkReflectors = autoBenchmarkReflectors
self.conferenceCalls = conferenceCalls
self.playerV2 = playerV2
self.devRequests = devRequests
self.fakeAds = fakeAds
@ -239,7 +235,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
self.dynamicStreaming = try container.decodeIfPresent(Bool.self, forKey: "dynamicStreaming_v2") ?? false
self.enableLocalTranslation = try container.decodeIfPresent(Bool.self, forKey: "enableLocalTranslation") ?? false
self.autoBenchmarkReflectors = try container.decodeIfPresent(Bool.self, forKey: "autoBenchmarkReflectors")
self.conferenceCalls = try container.decodeIfPresent(Bool.self, forKey: "conferenceCalls") ?? false
self.playerV2 = try container.decodeIfPresent(Bool.self, forKey: "playerV2") ?? false
self.devRequests = try container.decodeIfPresent(Bool.self, forKey: "devRequests") ?? false
self.fakeAds = try container.decodeIfPresent(Bool.self, forKey: "fakeAds") ?? false
@ -285,7 +280,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
try container.encode(self.dynamicStreaming, forKey: "dynamicStreaming")
try container.encode(self.enableLocalTranslation, forKey: "enableLocalTranslation")
try container.encodeIfPresent(self.autoBenchmarkReflectors, forKey: "autoBenchmarkReflectors")
try container.encodeIfPresent(self.conferenceCalls, forKey: "conferenceCalls")
try container.encodeIfPresent(self.playerV2, forKey: "playerV2")
try container.encodeIfPresent(self.devRequests, forKey: "devRequests")
try container.encodeIfPresent(self.fakeAds, forKey: "fakeAds")

View File

@ -555,12 +555,13 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
}
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)
} else if let item = topItem {
if item.file.isAnimatedSticker || item.file.isVideoSticker {
thumbnailItem = .animated(EngineMediaResource(item.file.resource), item.file.dimensions ?? PixelDimensions(width: 512, height: 512), item.file.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
let itemFile = item.file._parse()
if itemFile.isAnimatedSticker || itemFile.isVideoSticker {
thumbnailItem = .animated(EngineMediaResource(itemFile.resource), itemFile.dimensions ?? PixelDimensions(width: 512, height: 512), itemFile.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: itemFile), resource: itemFile.resource)
} else if let dimensions = itemFile.dimensions, let resource = chatMessageStickerResource(file: itemFile, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
resourceReference = MediaResourceReference.media(media: .standalone(media: itemFile), resource: resource)
}
}
@ -668,7 +669,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
case let .result(_, items, _):
let item = items[Int(value)]
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file.resource), width: 120, height: 120, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file._parse().resource), width: 120, height: 120, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
default:
break
}

View File

@ -314,12 +314,12 @@ private func mediaForSticker(documentId: Int64, account: Account) -> Signal<Tele
for view in view.orderedItemListsViews {
for entry in view.items {
if let file = entry.contents.get(SavedStickerItem.self)?.file {
if file.id?.id == documentId {
return file
if file.id.id == documentId {
return file._parse()
}
} else if let file = entry.contents.get(RecentMediaItem.self)?.media {
if file.id?.id == documentId {
return file
if file.id.id == documentId {
return file._parse()
}
}
}
@ -614,12 +614,12 @@ final class WatchStickersHandler: WatchRequestHandler {
outer: for view in view.orderedItemListsViews {
for entry in view.items {
if let file = entry.contents.get(SavedStickerItem.self)?.file {
if let sticker = makeBridgeDocument(file), !added.contains(sticker.documentId) {
if let sticker = makeBridgeDocument(file._parse()), !added.contains(sticker.documentId) {
stickers.append(sticker)
added.insert(sticker.documentId)
}
} else if let file = entry.contents.get(RecentMediaItem.self)?.media {
if let sticker = makeBridgeDocument(file), !added.contains(sticker.documentId) {
if let sticker = makeBridgeDocument(file._parse()), !added.contains(sticker.documentId) {
stickers.append(sticker)
added.insert(sticker.documentId)
}

View File

@ -2616,7 +2616,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)),
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: controller.botId)),
self.context.engine.stickers.loadedStickerPack(reference: .iconStatusEmoji, forceActualized: false)
|> map { result -> [TelegramMediaFile] in
|> map { result -> [TelegramMediaFile.Accessor] in
switch result {
case let .result(_, items, _):
return items.map(\.file)

View File

@ -18,7 +18,7 @@ private final class IconsNode: ASDisplayNode {
private let context: AccountContext
private var animationLayer: InlineStickerItemLayer?
private var files: [TelegramMediaFile]
private var files: [TelegramMediaFile.Accessor]
private var currentIndex = 0
private var switchingToNext = false
@ -26,7 +26,7 @@ private final class IconsNode: ASDisplayNode {
private var currentParams: (size: CGSize, theme: PresentationTheme)?
init(context: AccountContext, files: [TelegramMediaFile]) {
init(context: AccountContext, files: [TelegramMediaFile.Accessor]) {
self.context = context
self.files = files
@ -63,7 +63,7 @@ private final class IconsNode: ASDisplayNode {
disappearingAnimationLayer = self.animationLayer
self.switchingToNext = false
}
let file = self.files[self.currentIndex]
let file = self.files[self.currentIndex]._parse()
let emoji = ChatTextInputTextCustomEmojiAttribute(
interactivelySelectedFromPackId: nil,
fileId: file.fileId.id,
@ -132,7 +132,7 @@ private final class WebAppEmojiStatusAlertContentNode: AlertContentNode {
strings: PresentationStrings,
accountPeer: EnginePeer,
botName: String,
icons: [TelegramMediaFile],
icons: [TelegramMediaFile.Accessor],
actions: [TextAlertAction]
) {
self.strings = strings
@ -331,7 +331,7 @@ func webAppEmojiStatusAlertController(
context: AccountContext,
accountPeer: EnginePeer,
botName: String,
icons: [TelegramMediaFile],
icons: [TelegramMediaFile.Accessor],
completion: @escaping (Bool) -> Void
) -> AlertController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -56,7 +56,7 @@ genrule(
mkdir -p "$$BUILD_DIR/Public/libwebp"
PATH="$$PATH:$$CMAKE_DIR/cmake-3.23.1-macos-universal/CMake.app/Contents/bin" sh $$BUILD_DIR/build-webp-bazel.sh $$BUILD_ARCH "$$BUILD_DIR/libwebp" "$$BUILD_DIR" >/dev/null 2>&1
PATH="$$PATH:$$CMAKE_DIR/cmake-3.23.1-macos-universal/CMake.app/Contents/bin" sh $$BUILD_DIR/build-webp-bazel.sh $$BUILD_ARCH "$$BUILD_DIR/libwebp" "$$BUILD_DIR"
""" +
"\n".join([
"cp -f \"$$BUILD_DIR/libwebp/src/webp/{}\" \"$(location Public/webp/{})\"".format(header, header) for header in headers