mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 13:35:19 +00:00
Serialization update
This commit is contained in:
parent
f370102e44
commit
6c4070eb52
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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?
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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] {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)),
|
||||
|
@ -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
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
))
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import SwitchComponent
|
||||
import EntityKeyboard
|
||||
import AccountContext
|
||||
import HierarchyTrackingLayer
|
||||
import TelegramCore
|
||||
|
||||
private final class CaretIndicatorView: UIImageView {
|
||||
private let hierarchyTrackingLayer: HierarchyTrackingLayer
|
||||
|
@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 }
|
||||
|
2
third-party/webp/BUILD
vendored
2
third-party/webp/BUILD
vendored
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user