From faa765b6019ad1650329fb0a54296641d2f2a597 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Tue, 4 Mar 2025 14:13:07 +0100 Subject: [PATCH] Various optimizations --- ...ArchivedStickerPacksNoticeController.swift | 4 +- .../Sources/ChatMediaInputTrendingPane.swift | 13 +- .../Sources/FeaturedStickersScreen.swift | 16 +- .../Sources/StickerPaneSearchGlobaltem.swift | 4 +- .../Sources/ItemListStickerPackItem.swift | 13 +- .../Sources/ReactionContextNode.swift | 2 +- .../ArchivedStickerPacksController.swift | 12 +- .../FeaturedStickerPacksController.swift | 8 +- .../InstalledStickerPacksController.swift | 4 +- .../StickerPackPreviewController.swift | 1 + .../StickerPackPreviewControllerNode.swift | 7 +- .../Sources/StickerPackScreen.swift | 13 +- .../Sources/StickerResources.swift | 3 +- .../Models/ItemCollectionId.fbs | 6 + .../Models/StickerPackCollectionInfo.fbs | 19 ++ .../Sources/State/StickerManagement.swift | 6 +- .../SyncCore/SyncCore_CachedStickerPack.swift | 27 ++- .../SyncCore_FeaturedStickerPack.swift | 27 ++- .../SyncCore_StickerPackCollectionInfo.swift | 188 +++++++++++++++++- .../Peers/PeerSpecificStickerPack.swift | 2 +- .../Stickers/CachedStickerPack.swift | 26 +-- .../Stickers/LoadedStickerPack.swift | 2 +- .../Sources/Utils/FlatBuffersUtils.swift | 10 + .../Sources/AvatarEditorScreen.swift | 4 +- .../Sources/ChatMessageDateHeader.swift | 12 +- .../Sources/ChatEntityKeyboardInputNode.swift | 4 +- .../StickerPaneSearchContentNode.swift | 5 +- .../EmojiStatusSelectionComponent.swift | 2 +- .../Sources/EmojiPagerContentComponent.swift | 3 + .../Sources/EmojiPagerContentSignals.swift | 28 +-- .../Sources/ForumCreateTopicScreen.swift | 2 +- .../GroupStickerPackSetupController.swift | 6 +- .../GroupStickerSearchContainerNode.swift | 2 +- .../Sources/StickerPickerScreen.swift | 4 +- .../TelegramUI/Sources/AppDelegate.swift | 8 + .../Chat/ChatControllerLoadDisplayNode.swift | 45 +++-- .../Sources/ChatHistoryListNode.swift | 6 +- .../ChatInterfaceStateContextMenus.swift | 2 +- 38 files changed, 421 insertions(+), 125 deletions(-) create mode 100644 submodules/TelegramCore/FlatSerialization/Models/ItemCollectionId.fbs create mode 100644 submodules/TelegramCore/FlatSerialization/Models/StickerPackCollectionInfo.fbs diff --git a/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift b/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift index 0e1062e7dc..8825973840 100644 --- a/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift +++ b/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift @@ -15,7 +15,7 @@ import ItemListStickerPackItem private struct ArchivedStickersNoticeEntry: Comparable, Identifiable { let index: Int - let info: StickerPackCollectionInfo + let info: StickerPackCollectionInfo.Accessor let topItem: StickerPackItem? let count: String @@ -135,7 +135,7 @@ private final class ArchivedStickersNoticeAlertContentNode: AlertContentNode { } else { countTitle = presentationData.strings.StickerPack_StickerCount(pack.0.count) } - entries.append(ArchivedStickersNoticeEntry(index: index, info: pack.0, topItem: pack.1, count: countTitle)) + entries.append(ArchivedStickersNoticeEntry(index: index, info: StickerPackCollectionInfo.Accessor(pack.0), topItem: pack.1, count: countTitle)) index += 1 } diff --git a/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift b/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift index 35d2f53be1..6d6b9368cc 100644 --- a/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift +++ b/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift @@ -30,7 +30,7 @@ public final class TrendingPaneInteraction { public final class TrendingPanePackEntry: Identifiable, Comparable { public let index: Int - public let info: StickerPackCollectionInfo + public let info: StickerPackCollectionInfo.Accessor public let theme: PresentationTheme public let strings: PresentationStrings public let topItems: [StickerPackItem] @@ -38,7 +38,7 @@ public final class TrendingPanePackEntry: Identifiable, Comparable { public let unread: Bool public let topSeparator: Bool - public init(index: Int, info: StickerPackCollectionInfo, theme: PresentationTheme, strings: PresentationStrings, topItems: [StickerPackItem], installed: Bool, unread: Bool, topSeparator: Bool) { + public init(index: Int, info: StickerPackCollectionInfo.Accessor, theme: PresentationTheme, strings: PresentationStrings, topItems: [StickerPackItem], installed: Bool, unread: Bool, topSeparator: Bool) { self.index = index self.info = info self.theme = theme @@ -88,9 +88,9 @@ public final class TrendingPanePackEntry: Identifiable, Comparable { public func item(context: AccountContext, interaction: TrendingPaneInteraction, grid: Bool) -> GridItem { let info = self.info return StickerPaneSearchGlobalItem(context: context, theme: self.theme, strings: self.strings, listAppearance: false, info: self.info, topItems: self.topItems, topSeparator: self.topSeparator, regularInsets: false, installed: self.installed, unread: self.unread, open: { - interaction.openPack(info) + interaction.openPack(info._parse()) }, install: { - interaction.installPack(info) + interaction.installPack(info._parse()) }, getItemIsPreviewed: { item in return interaction.getItemIsPreviewed(item) }, itemContext: interaction.itemContext) @@ -272,16 +272,17 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { if installed { return .complete() } else { + let parsedInfo = info._parse() return preloadedStickerPackThumbnail(account: context.account, info: info, items: items) |> filter { $0 } |> ignoreValues |> then( - context.engine.stickers.addStickerPackInteractively(info: info, items: items) + context.engine.stickers.addStickerPackInteractively(info: parsedInfo, items: items) |> ignoreValues ) |> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in } - |> then(.single((info, items))) + |> then(.single((parsedInfo, items))) } case .fetching: break diff --git a/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift b/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift index 32ccedd180..25d2f27a6d 100644 --- a/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift +++ b/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift @@ -35,7 +35,7 @@ private final class FeaturedInteraction { private final class FeaturedPackEntry: Identifiable, Comparable { let index: Int - let info: StickerPackCollectionInfo + let info: StickerPackCollectionInfo.Accessor let theme: PresentationTheme let strings: PresentationStrings let topItems: [StickerPackItem] @@ -44,7 +44,7 @@ private final class FeaturedPackEntry: Identifiable, Comparable { let topSeparator: Bool let regularInsets: Bool - init(index: Int, info: StickerPackCollectionInfo, theme: PresentationTheme, strings: PresentationStrings, topItems: [StickerPackItem], installed: Bool, unread: Bool, topSeparator: Bool, regularInsets: Bool = false) { + init(index: Int, info: StickerPackCollectionInfo.Accessor, theme: PresentationTheme, strings: PresentationStrings, topItems: [StickerPackItem], installed: Bool, unread: Bool, topSeparator: Bool, regularInsets: Bool = false) { self.index = index self.info = info self.theme = theme @@ -98,9 +98,9 @@ private final class FeaturedPackEntry: Identifiable, Comparable { func item(context: AccountContext, interaction: FeaturedInteraction, isOther: Bool) -> GridItem { let info = self.info return StickerPaneSearchGlobalItem(context: context, theme: self.theme, strings: self.strings, listAppearance: true, fillsRow: false, info: self.info, topItems: self.topItems, topSeparator: self.topSeparator, regularInsets: self.regularInsets, installed: self.installed, unread: self.unread, open: { - interaction.openPack(info) + interaction.openPack(info._parse()) }, install: { - interaction.installPack(info, !self.installed) + interaction.installPack(info._parse(), !self.installed) }, getItemIsPreviewed: { item in return interaction.getItemIsPreviewed(item) }, itemContext: interaction.itemContext, sectionTitle: isOther ? self.strings.FeaturedStickers_OtherSection : nil) @@ -1041,7 +1041,7 @@ private enum FeaturedSearchEntryId: Equatable, Hashable { private enum FeaturedSearchEntry: Identifiable, Comparable { case sticker(index: Int, code: String?, stickerItem: FoundStickerItem, theme: PresentationTheme) - case global(index: Int, info: StickerPackCollectionInfo, topItems: [StickerPackItem], installed: Bool, topSeparator: Bool) + case global(index: Int, info: StickerPackCollectionInfo.Accessor, topItems: [StickerPackItem], installed: Bool, topSeparator: Bool) var stableId: FeaturedSearchEntryId { switch self { @@ -1108,9 +1108,9 @@ private enum FeaturedSearchEntry: Identifiable, Comparable { }) case let .global(_, info, topItems, installed, topSeparator): return StickerPaneSearchGlobalItem(context: context, theme: theme, strings: strings, listAppearance: true, fillsRow: true, info: info, topItems: topItems, topSeparator: topSeparator, regularInsets: false, installed: installed, unread: false, open: { - interaction.open(info) + interaction.open(info._parse()) }, install: { - interaction.install(info, topItems, !installed) + interaction.install(info._parse(), topItems, !installed) }, getItemIsPreviewed: { item in return interaction.getItemIsPreviewed(item) }, itemContext: itemContext) @@ -1436,7 +1436,7 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode { } } } - entries.append(.global(index: index, info: info, topItems: topItems, installed: installed, topSeparator: !isFirstGlobal)) + entries.append(.global(index: index, info: StickerPackCollectionInfo.Accessor(info), topItems: topItems, installed: installed, topSeparator: !isFirstGlobal)) isFirstGlobal = false index += 1 } diff --git a/submodules/FeaturedStickersScreen/Sources/StickerPaneSearchGlobaltem.swift b/submodules/FeaturedStickersScreen/Sources/StickerPaneSearchGlobaltem.swift index 5431703c70..7cf0cfffe2 100644 --- a/submodules/FeaturedStickersScreen/Sources/StickerPaneSearchGlobaltem.swift +++ b/submodules/FeaturedStickersScreen/Sources/StickerPaneSearchGlobaltem.swift @@ -84,7 +84,7 @@ public final class StickerPaneSearchGlobalItem: GridItem { public let strings: PresentationStrings public let listAppearance: Bool public let fillsRow: Bool - public let info: StickerPackCollectionInfo + public let info: StickerPackCollectionInfo.Accessor public let topItems: [StickerPackItem] public let topSeparator: Bool public let regularInsets: Bool @@ -111,7 +111,7 @@ public final class StickerPaneSearchGlobalItem: GridItem { return (128.0 + additionalHeight, self.fillsRow) } - public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, listAppearance: Bool, fillsRow: Bool = true, info: StickerPackCollectionInfo, topItems: [StickerPackItem], topSeparator: Bool, regularInsets: Bool, installed: Bool, installing: Bool = false, unread: Bool, open: @escaping () -> Void, install: @escaping () -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, itemContext: StickerPaneSearchGlobalItemContext, sectionTitle: String? = nil) { + public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, listAppearance: Bool, fillsRow: Bool = true, info: StickerPackCollectionInfo.Accessor, topItems: [StickerPackItem], topSeparator: Bool, regularInsets: Bool, installed: Bool, installing: Bool = false, unread: Bool, open: @escaping () -> Void, install: @escaping () -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, itemContext: StickerPaneSearchGlobalItemContext, sectionTitle: String? = nil) { self.context = context self.theme = theme self.strings = strings diff --git a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift index 55beb7bc22..7fd1c4f3b4 100644 --- a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift +++ b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift @@ -40,7 +40,7 @@ public enum ItemListStickerPackItemControl: Equatable { public final class ItemListStickerPackItem: ListViewItem, ItemListItem { let presentationData: ItemListPresentationData let context: AccountContext - let packInfo: StickerPackCollectionInfo + let packInfo: StickerPackCollectionInfo.Accessor let itemCount: String let topItem: StickerPackItem? let unread: Bool @@ -56,7 +56,7 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem { let removePack: () -> Void let toggleSelected: () -> Void - public init(presentationData: ItemListPresentationData, context: AccountContext, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, style: ItemListStyle = .blocks, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) { + public init(presentationData: ItemListPresentationData, context: AccountContext, packInfo: StickerPackCollectionInfo.Accessor, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, style: ItemListStyle = .blocks, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) { self.presentationData = presentationData self.context = context self.packInfo = packInfo @@ -487,7 +487,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { var thumbnailItem: StickerPackThumbnailItem? var resourceReference: MediaResourceReference? - if let thumbnail = item.packInfo.thumbnail { + if item.packInfo.hasThumbnail, let thumbnail = item.packInfo._parse().thumbnail { if thumbnail.typeHint != .generic { thumbnailItem = .animated(thumbnail.resource, thumbnail.dimensions, thumbnail.typeHint == .video, item.packInfo.flags.contains(.isCustomTemplateEmoji)) } else { @@ -845,7 +845,12 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { var imageSize = PixelDimensions(width: 512, height: 512) var immediateThumbnailData: Data? if let data = item.packInfo.immediateThumbnailData { - if item.packInfo.thumbnail?.typeHint == .video || item.topItem?.file.isVideoSticker == true { + var isVideoTypeHint = false + if item.packInfo.hasThumbnail, let thumbnail = item.packInfo._parse().thumbnail { + isVideoTypeHint = thumbnail.typeHint == .video + } + + if isVideoTypeHint || item.topItem?.file.isVideoSticker == true { imageSize = PixelDimensions(width: 100, height: 100) } immediateThumbnailData = data diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index 03f86e7a05..bc4608d87b 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -1741,7 +1741,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate { if let strongSelf = self { strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId, scrollToGroup: true)) } - let _ = strongSelf.context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start() + let _ = strongSelf.context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info._parse(), items: featuredEmojiPack.topItems).start() break } diff --git a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift index 9639d7bfce..4d143040ca 100644 --- a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift @@ -141,7 +141,7 @@ private enum ArchivedStickerPacksEntry: ItemListNodeEntry { case let .info(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing, selected): - return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .installation(installed: false), editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: StickerPackCollectionInfo.Accessor(info), itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .installation(installed: false), editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { current, previous in arguments.setPackIdWithRevealedOptions(current, previous) @@ -323,11 +323,12 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + let parsedInfo = info._parse() + return context.engine.stickers.addStickerPackInteractively(info: parsedInfo, items: items) |> ignoreValues |> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in } - |> then(.single((info, items))) + |> then(.single((parsedInfo, items))) } case .fetching: break @@ -489,11 +490,12 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + let parsedInfo = info._parse() + return context.engine.stickers.addStickerPackInteractively(info: parsedInfo, items: items) |> ignoreValues |> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in } - |> then(.single((info, items))) + |> then(.single((parsedInfo, items))) } case .fetching: break diff --git a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift index 63c746cac6..e0baafe727 100644 --- a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift @@ -34,7 +34,7 @@ private enum FeaturedStickerPacksEntryId: Hashable { } private enum FeaturedStickerPacksEntry: ItemListNodeEntry { - case pack(Int32, PresentationTheme, PresentationStrings, StickerPackCollectionInfo, Bool, StickerPackItem?, String, Bool, Bool) + case pack(Int32, PresentationTheme, PresentationStrings, StickerPackCollectionInfo.Accessor, Bool, StickerPackItem?, String, Bool, Bool) var section: ItemListSectionId { switch self { @@ -103,10 +103,10 @@ private enum FeaturedStickerPacksEntry: ItemListNodeEntry { switch self { case let .pack(_, _, _, info, unread, topItem, count, playAnimatedStickers, installed): return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { - arguments.openStickerPack(info) + arguments.openStickerPack(info._parse()) }, setPackIdWithRevealedOptions: { _, _ in }, addPack: { - arguments.addPack(info) + arguments.addPack(info._parse()) }, removePack: { }, toggleSelected: { }) @@ -178,7 +178,7 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break diff --git a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift index b68a005ded..e231483dcb 100644 --- a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift @@ -433,7 +433,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry { case let .packsTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing, selected): - return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: StickerPackCollectionInfo.Accessor(info), itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { current, previous in arguments.setPackIdWithRevealedOptions(current, previous) @@ -853,7 +853,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewController.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewController.swift index 41d2a1e7e2..a17ace08a1 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewController.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewController.swift @@ -196,6 +196,7 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese case let .result(info, items, _): var preloadSignals: [Signal] = [] + let info = info._parse() if let thumbnail = info.thumbnail { let signal = Signal { subscriber in let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start() diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift index 95620529f1..8563133bb4 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift @@ -539,11 +539,12 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, ASScrol guard let strongSelf = self, let (positionInList, _) = indexAndItems else { return } - strongSelf.actionPerformed?(info, items, .remove(positionInList: positionInList)) + strongSelf.actionPerformed?(info._parse(), items, .remove(positionInList: positionInList)) }) } else { - let _ = self.context.engine.stickers.addStickerPackInteractively(info: info, items: items).start() - self.actionPerformed?(info, items, .add) + let parsedInfo = info._parse() + let _ = self.context.engine.stickers.addStickerPackInteractively(info: parsedInfo, items: items).start() + self.actionPerformed?(parsedInfo, items, .add) } self.cancelButtonPressed() default: diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index 568778913c..0ae1c95212 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -459,7 +459,7 @@ private final class StickerPackContainer: ASDisplayNode { var contents: [LoadedStickerPack] = [] for (info, items, isInstalled) in strongSelf.currentStickerPacks { - contents.append(.result(info: info, items: items, installed: isInstalled)) + contents.append(.result(info: StickerPackCollectionInfo.Accessor(info), items: items, installed: isInstalled)) } strongSelf.updateStickerPackContents(contents, hasPremium: false) @@ -476,7 +476,7 @@ private final class StickerPackContainer: ASDisplayNode { var contents: [LoadedStickerPack] = [] for (info, items, isInstalled) in strongSelf.currentStickerPacks { - contents.append(.result(info: info, items: items, installed: isInstalled)) + contents.append(.result(info: StickerPackCollectionInfo.Accessor(info), items: items, installed: isInstalled)) } strongSelf.updateStickerPackContents(contents, hasPremium: false) @@ -1534,7 +1534,7 @@ private final class StickerPackContainer: ASDisplayNode { self.requestDismiss() dismissed = true case .navigatedNext, .ignored: - self.updateStickerPackContents([.result(info: info, items: items, installed: !installed)], hasPremium: false) + self.updateStickerPackContents([.result(info: StickerPackCollectionInfo.Accessor(info), items: items, installed: !installed)], hasPremium: false) } let actionPerformed = self.controller?.actionPerformed @@ -1707,11 +1707,11 @@ private final class StickerPackContainer: ASDisplayNode { var installedCount = 0 for content in contents { if case let .result(info, items, isInstalled) = content { - entries.append(.emojis(index: index, stableId: index, info: info, items: items, title: info.title, isInstalled: isInstalled)) + entries.append(.emojis(index: index, stableId: index, info: info._parse(), items: items, title: info.title, isInstalled: isInstalled)) if isInstalled { installedCount += 1 } - currentStickerPacks.append((info, items, isInstalled)) + currentStickerPacks.append((info._parse(), items, isInstalled)) } index += 1 } @@ -1772,6 +1772,9 @@ private final class StickerPackContainer: ASDisplayNode { case let .result(info, items, installed): isEditable = info.flags.contains(.isCreator) && !info.flags.contains(.isEmoji) self.onReady() + + let info = info._parse() + if !items.isEmpty && self.currentStickerPack == nil { if let _ = self.validLayout, abs(self.expandScrollProgress - 1.0) < .ulpOfOne { scrollToItem = GridNodeScrollToItem(index: 0, position: .top(0.0), transition: .immediate, directionHint: .up, adjustForSection: false) diff --git a/submodules/StickerResources/Sources/StickerResources.swift b/submodules/StickerResources/Sources/StickerResources.swift index 5307aadce8..229dbc7f6b 100644 --- a/submodules/StickerResources/Sources/StickerResources.swift +++ b/submodules/StickerResources/Sources/StickerResources.swift @@ -587,7 +587,8 @@ public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaReso } } -public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCollectionInfo, items: [ItemCollectionItem]) -> Signal { +public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCollectionInfo.Accessor, items: [ItemCollectionItem]) -> Signal { + let info = info._parse() if let thumbnail = info.thumbnail { let signal = Signal { subscriber in let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start() diff --git a/submodules/TelegramCore/FlatSerialization/Models/ItemCollectionId.fbs b/submodules/TelegramCore/FlatSerialization/Models/ItemCollectionId.fbs new file mode 100644 index 0000000000..77c7f55173 --- /dev/null +++ b/submodules/TelegramCore/FlatSerialization/Models/ItemCollectionId.fbs @@ -0,0 +1,6 @@ +namespace TelegramCore; + +struct ItemCollectionId { + namespace: int; + id: int64; +} diff --git a/submodules/TelegramCore/FlatSerialization/Models/StickerPackCollectionInfo.fbs b/submodules/TelegramCore/FlatSerialization/Models/StickerPackCollectionInfo.fbs new file mode 100644 index 0000000000..9df9aa0605 --- /dev/null +++ b/submodules/TelegramCore/FlatSerialization/Models/StickerPackCollectionInfo.fbs @@ -0,0 +1,19 @@ +include "ItemCollectionId.fbs"; +include "TelegramMediaImageRepresentation.fbs"; + +namespace TelegramCore; + +table StickerPackCollectionInfo { + id:ItemCollectionId (id: 0, required); + flags:int32 (id: 1); + accessHash:int64 (id: 2); + title:string (id: 3, required); + shortName:string (id: 4, required); + thumbnail:TelegramMediaImageRepresentation (id: 5); + thumbnailFileId:int64 (id: 6); + immediateThumbnailData:[ubyte] (id: 7); + hash:int32 (id: 8); + count:int32 (id: 9); +} + +root_type StickerPackCollectionInfo; diff --git a/submodules/TelegramCore/Sources/State/StickerManagement.swift b/submodules/TelegramCore/Sources/State/StickerManagement.swift index a4ac5b9360..e159022381 100644 --- a/submodules/TelegramCore/Sources/State/StickerManagement.swift +++ b/submodules/TelegramCore/Sources/State/StickerManagement.swift @@ -159,7 +159,7 @@ func updatedFeaturedStickerPacks(network: Network, postbox: Postbox, category: F items = Array(items.prefix(5)) } } - updatedPacks.append(FeaturedStickerPackItem(info: info, topItems: items, unread: unreadIds.contains(info.id.id))) + updatedPacks.append(FeaturedStickerPackItem(info: StickerPackCollectionInfo.Accessor(info), topItems: items, unread: unreadIds.contains(info.id.id))) } let isPremium = flags & (1 << 0) != 0 return .content(FeaturedListContent( @@ -194,7 +194,7 @@ func updatedFeaturedStickerPacks(network: Network, postbox: Postbox, category: F items = previousPack.topItems } } - updatedPacks.append(FeaturedStickerPackItem(info: info, topItems: items, unread: unreadIds.contains(info.id.id))) + updatedPacks.append(FeaturedStickerPackItem(info: StickerPackCollectionInfo.Accessor(info), topItems: items, unread: unreadIds.contains(info.id.id))) } let isPremium = flags & (1 << 0) != 0 return .content(FeaturedListContent( @@ -247,7 +247,7 @@ public func requestOldFeaturedStickerPacks(network: Network, postbox: Postbox, o var updatedPacks: [FeaturedStickerPackItem] = [] for set in sets { let (info, items) = parsePreviewStickerSet(set, namespace: Namespaces.ItemCollection.CloudStickerPacks) - updatedPacks.append(FeaturedStickerPackItem(info: info, topItems: items, unread: unreadIds.contains(info.id.id))) + updatedPacks.append(FeaturedStickerPackItem(info: StickerPackCollectionInfo.Accessor(info), topItems: items, unread: unreadIds.contains(info.id.id))) } return updatedPacks } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedStickerPack.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedStickerPack.swift index dd8774e9e3..01bfe20a51 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedStickerPack.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedStickerPack.swift @@ -1,12 +1,15 @@ +import Foundation import Postbox +import FlatBuffers +import FlatSerialization public final class CachedStickerPack: Codable { - public let info: StickerPackCollectionInfo? + public let info: StickerPackCollectionInfo.Accessor? public let items: [StickerPackItem] public let hash: Int32 public init(info: StickerPackCollectionInfo?, items: [StickerPackItem], hash: Int32) { - self.info = info + self.info = info.flatMap(StickerPackCollectionInfo.Accessor.init) self.items = items self.hash = hash } @@ -14,8 +17,12 @@ public final class CachedStickerPack: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - if let infoData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "in") { - self.info = StickerPackCollectionInfo(decoder: PostboxDecoder(buffer: MemoryBuffer(data: infoData.data))) + if let serializedInfoData = try container.decodeIfPresent(Data.self, forKey: "ind") { + var byteBuffer = ByteBuffer(data: serializedInfoData) + self.info = StickerPackCollectionInfo.Accessor(FlatBuffers_getRoot(byteBuffer: &byteBuffer) as TelegramCore_StickerPackCollectionInfo, serializedInfoData) + } else if let infoData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "in") { + let info = StickerPackCollectionInfo(decoder: PostboxDecoder(buffer: MemoryBuffer(data: infoData.data))) + self.info = StickerPackCollectionInfo.Accessor(info) } else { self.info = nil } @@ -31,7 +38,17 @@ public final class CachedStickerPack: Codable { var container = encoder.container(keyedBy: StringCodingKey.self) if let info = self.info { - try container.encode(PostboxEncoder().encodeObjectToRawData(info), forKey: "in") + if let infoData = info._wrappedData { + try container.encode(infoData, forKey: "ind") + } else if let info = info._wrappedObject { + var builder = FlatBufferBuilder(initialSize: 1024) + let value = info.encodeToFlatBuffers(builder: &builder) + builder.finish(offset: value) + let serializedInstantPage = builder.data + try container.encode(serializedInstantPage, forKey: "ind") + } else { + preconditionFailure() + } } else { try container.encodeNil(forKey: "in") } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_FeaturedStickerPack.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_FeaturedStickerPack.swift index 701b940979..94f9de63b9 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_FeaturedStickerPack.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_FeaturedStickerPack.swift @@ -1,5 +1,7 @@ import Foundation import Postbox +import FlatBuffers +import FlatSerialization public struct FeaturedStickerPackItemId { public let rawValue: MemoryBuffer @@ -22,11 +24,11 @@ public struct FeaturedStickerPackItemId { } public final class FeaturedStickerPackItem: Codable { - public let info: StickerPackCollectionInfo + public let info: StickerPackCollectionInfo.Accessor public let topItems: [StickerPackItem] public let unread: Bool - public init(info: StickerPackCollectionInfo, topItems: [StickerPackItem], unread: Bool) { + public init(info: StickerPackCollectionInfo.Accessor, topItems: [StickerPackItem], unread: Bool) { self.info = info self.topItems = topItems self.unread = unread @@ -35,8 +37,13 @@ public final class FeaturedStickerPackItem: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - let infoData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "i") - self.info = StickerPackCollectionInfo(decoder: PostboxDecoder(buffer: MemoryBuffer(data: infoData.data))) + if let serializedInfoData = try container.decodeIfPresent(Data.self, forKey: "infd") { + var byteBuffer = ByteBuffer(data: serializedInfoData) + self.info = StickerPackCollectionInfo.Accessor(FlatBuffers_getRoot(byteBuffer: &byteBuffer) as TelegramCore_StickerPackCollectionInfo, serializedInfoData) + } else { + let infoData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "i") + self.info = StickerPackCollectionInfo.Accessor(StickerPackCollectionInfo(decoder: PostboxDecoder(buffer: MemoryBuffer(data: infoData.data)))) + } self.topItems = (try container.decode([AdaptedPostboxDecoder.RawObjectData].self, forKey: "t")).map { itemData in return StickerPackItem(decoder: PostboxDecoder(buffer: MemoryBuffer(data: itemData.data))) @@ -48,7 +55,17 @@ public final class FeaturedStickerPackItem: Codable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) - try container.encode(PostboxEncoder().encodeObjectToRawData(self.info), forKey: "i") + if let infoData = self.info._wrappedData { + try container.encode(infoData, forKey: "infd") + } else if let info = self.info._wrappedObject { + var builder = FlatBufferBuilder(initialSize: 1024) + let value = info.encodeToFlatBuffers(builder: &builder) + builder.finish(offset: value) + let serializedInstantPage = builder.data + try container.encode(serializedInstantPage, forKey: "infd") + } else { + preconditionFailure() + } try container.encode(self.topItems.map { item in return PostboxEncoder().encodeObjectToRawData(item) }, forKey: "t") diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StickerPackCollectionInfo.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StickerPackCollectionInfo.swift index a9f717f43d..1af0e79bda 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StickerPackCollectionInfo.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StickerPackCollectionInfo.swift @@ -1,5 +1,7 @@ import Foundation import Postbox +import FlatBuffers +import FlatSerialization public struct StickerPackCollectionInfoFlags: OptionSet { public var rawValue: Int32 @@ -39,7 +41,6 @@ public struct StickerPackCollectionInfoFlags: OptionSet { public static let isCreator = StickerPackCollectionInfoFlags(rawValue: 1 << 7) } - public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable { public let id: ItemCollectionId public let flags: StickerPackCollectionInfoFlags @@ -102,6 +103,56 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable { encoder.encodeInt32(self.hash, forKey: "h") encoder.encodeInt32(self.flags.rawValue, forKey: "f") encoder.encodeInt32(self.count, forKey: "n") + + #if DEBUG + var builder = FlatBufferBuilder(initialSize: 1024) + let offset = self.encodeToFlatBuffers(builder: &builder) + builder.finish(offset: offset) + let serializedData = builder.data + var byteBuffer = ByteBuffer(data: serializedData) + let deserializedValue = FlatBuffers_getRoot(byteBuffer: &byteBuffer) as TelegramCore_StickerPackCollectionInfo + let parsedValue = try! StickerPackCollectionInfo(flatBuffersObject: deserializedValue) + assert(self == parsedValue) + #endif + } + + public init(flatBuffersObject: TelegramCore_StickerPackCollectionInfo) throws { + self.id = ItemCollectionId(flatBuffersObject.id) + self.flags = StickerPackCollectionInfoFlags(rawValue: flatBuffersObject.flags) + self.accessHash = flatBuffersObject.accessHash + self.title = flatBuffersObject.title + self.shortName = flatBuffersObject.shortName + self.thumbnail = try flatBuffersObject.thumbnail.flatMap(TelegramMediaImageRepresentation.init(flatBuffersObject:)) + self.thumbnailFileId = flatBuffersObject.thumbnailFileId == Int64.min ? nil : flatBuffersObject.thumbnailFileId + self.immediateThumbnailData = flatBuffersObject.immediateThumbnailData.isEmpty ? nil : Data(flatBuffersObject.immediateThumbnailData) + self.hash = flatBuffersObject.hash + self.count = flatBuffersObject.count + } + + public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset { + let titleOffset = builder.create(string: self.title) + let shortNameOffset = builder.create(string: self.shortName) + let thumbnailOffset = self.thumbnail.flatMap { $0.encodeToFlatBuffers(builder: &builder) } + let immediateThumbnailDataOffset = self.immediateThumbnailData.flatMap { builder.createVector(bytes: $0) } + + let start = TelegramCore_StickerPackCollectionInfo.startStickerPackCollectionInfo(&builder) + + TelegramCore_StickerPackCollectionInfo.add(id: self.id.asFlatBuffersObject(), &builder) + TelegramCore_StickerPackCollectionInfo.add(flags: self.flags.rawValue, &builder) + TelegramCore_StickerPackCollectionInfo.add(accessHash: self.accessHash, &builder) + TelegramCore_StickerPackCollectionInfo.add(title: titleOffset, &builder) + TelegramCore_StickerPackCollectionInfo.add(shortName: shortNameOffset, &builder) + if let thumbnailOffset { + TelegramCore_StickerPackCollectionInfo.add(thumbnail: thumbnailOffset, &builder) + } + TelegramCore_StickerPackCollectionInfo.add(thumbnailFileId: self.thumbnailFileId ?? Int64.min, &builder) + if let immediateThumbnailDataOffset { + TelegramCore_StickerPackCollectionInfo.addVectorOf(immediateThumbnailData: immediateThumbnailDataOffset, &builder) + } + TelegramCore_StickerPackCollectionInfo.add(hash: self.hash, &builder) + TelegramCore_StickerPackCollectionInfo.add(count: self.count, &builder) + + return TelegramCore_StickerPackCollectionInfo.endStickerPackCollectionInfo(&builder, start: start) } public static func ==(lhs: StickerPackCollectionInfo, rhs: StickerPackCollectionInfo) -> Bool { @@ -129,6 +180,141 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable { if lhs.count != rhs.count { return false } + if lhs.thumbnail != rhs.thumbnail { + return false + } return true } } + +public extension StickerPackCollectionInfo { + struct Accessor: Equatable { + let _wrappedObject: StickerPackCollectionInfo? + let _wrapped: TelegramCore_StickerPackCollectionInfo? + let _wrappedData: Data? + + public init(_ wrapped: TelegramCore_StickerPackCollectionInfo, _ _wrappedData: Data) { + self._wrapped = wrapped + self._wrappedData = _wrappedData + self._wrappedObject = nil + } + + public init(_ wrapped: StickerPackCollectionInfo) { + self._wrapped = nil + self._wrappedData = nil + self._wrappedObject = wrapped + } + + public func _parse() -> StickerPackCollectionInfo { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject + } else { + return try! StickerPackCollectionInfo(flatBuffersObject: self._wrapped!) + } + } + + public static func ==(lhs: StickerPackCollectionInfo.Accessor, rhs: StickerPackCollectionInfo.Accessor) -> Bool { + if let lhsWrappedObject = lhs._wrappedObject, let rhsWrappedObject = rhs._wrappedObject { + return lhsWrappedObject == rhsWrappedObject + } else if let lhsWrappedData = lhs._wrappedData, let rhsWrappedData = rhs._wrappedData { + return lhsWrappedData == rhsWrappedData + } else { + return lhs._parse() == rhs._parse() + } + } + } +} + +public extension StickerPackCollectionInfo.Accessor { + var id: ItemCollectionId { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.id + } + + return ItemCollectionId(self._wrapped!.id) + } + + var accessHash: Int64 { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.accessHash + } + + return self._wrapped!.accessHash + } + + var flags: StickerPackCollectionInfoFlags { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.flags + } + + return StickerPackCollectionInfoFlags(rawValue: self._wrapped!.flags) + } + + var title: String { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.title + } + + return self._wrapped!.title + } + + var shortName: String { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.shortName + } + + return self._wrapped!.shortName + } + + var hash: Int32 { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.hash + } + + return self._wrapped!.hash + } + + var immediateThumbnailData: Data? { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.immediateThumbnailData + } + + return self._wrapped!.immediateThumbnailData.isEmpty ? nil : Data(self._wrapped!.immediateThumbnailData) + } + + var thumbnailFileId: Int64? { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.thumbnailFileId + } + + return self._wrapped!.thumbnailFileId == Int64.min ? nil : self._wrapped!.thumbnailFileId + } + + var count: Int32 { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.count + } + + return self._wrapped!.count + } + + var hasThumbnail: Bool { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.thumbnail != nil + } + + return self._wrapped!.thumbnail != nil + } + + var thumbnailDimensions: PixelDimensions? { + if let _wrappedObject = self._wrappedObject { + return _wrappedObject.thumbnail?.dimensions + } + + if let thumbnail = self._wrapped!.thumbnail { + return PixelDimensions(width: thumbnail.width, height: thumbnail.height) + } else { + return nil + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerSpecificStickerPack.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerSpecificStickerPack.swift index 082d0ca9d7..46709b7a8d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerSpecificStickerPack.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerSpecificStickerPack.swift @@ -12,7 +12,7 @@ private struct WrappedStickerPackCollectionInfo: Equatable { } public struct PeerSpecificStickerPackData { - public let packInfo: (StickerPackCollectionInfo, [ItemCollectionItem])? + public let packInfo: (StickerPackCollectionInfo.Accessor, [ItemCollectionItem])? public let canSetup: Bool } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/CachedStickerPack.swift b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/CachedStickerPack.swift index d21db933e6..5f59f46ce1 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/CachedStickerPack.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/CachedStickerPack.swift @@ -6,7 +6,7 @@ import MurMurHash32 public enum CachedStickerPackResult { case none case fetching - case result(StickerPackCollectionInfo, [StickerPackItem], Bool) + case result(StickerPackCollectionInfo.Accessor, [StickerPackItem], Bool) } func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo, items: [StickerPackItem], reference: StickerPackReference? = nil) { @@ -228,7 +228,7 @@ func _internal_cachedStickerPack(postbox: Postbox, network: Network, reference: if let result = result { cacheStickerPack(transaction: transaction, info: result.0, items: result.1, reference: reference) let currentInfo = transaction.getItemCollectionInfo(collectionId: result.0.id) as? StickerPackCollectionInfo - return .result(result.0, result.1, currentInfo != nil) + return .result(StickerPackCollectionInfo.Accessor(result.0), result.1, currentInfo != nil) } else { return .none } @@ -244,7 +244,7 @@ func _internal_cachedStickerPack(postbox: Postbox, network: Network, reference: } } -func cachedStickerPack(transaction: Transaction, reference: StickerPackReference) -> (StickerPackCollectionInfo, [StickerPackItem], Bool)? { +func cachedStickerPack(transaction: Transaction, reference: StickerPackReference) -> (StickerPackCollectionInfo.Accessor, [StickerPackItem], Bool)? { let namespaces: [Int32] = [Namespaces.ItemCollection.CloudStickerPacks, Namespaces.ItemCollection.CloudMaskPacks, Namespaces.ItemCollection.CloudEmojiPacks] switch reference { case let .id(id, _): @@ -252,7 +252,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -267,7 +267,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if info.shortName.lowercased() == shortName { let items = transaction.getItemCollectionItems(collectionId: info.id) if !items.isEmpty { - return (info, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(info), items.compactMap { $0 as? StickerPackItem }, true) } } } @@ -282,7 +282,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -294,7 +294,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -306,7 +306,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -318,7 +318,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -330,7 +330,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -342,7 +342,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -354,7 +354,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { @@ -366,7 +366,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) if !items.isEmpty { - return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true) + return (StickerPackCollectionInfo.Accessor(currentInfo), items.compactMap { $0 as? StickerPackItem }, true) } } if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/LoadedStickerPack.swift b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/LoadedStickerPack.swift index 8e1ae1f68d..369d5a5c7f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/LoadedStickerPack.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/LoadedStickerPack.swift @@ -37,7 +37,7 @@ extension StickerPackReference { public enum LoadedStickerPack { case fetching case none - case result(info: StickerPackCollectionInfo, items: [StickerPackItem], installed: Bool) + case result(info: StickerPackCollectionInfo.Accessor, items: [StickerPackItem], installed: Bool) } func updatedRemoteStickerPack(postbox: Postbox, network: Network, reference: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [StickerPackItem])?, NoError> { diff --git a/submodules/TelegramCore/Sources/Utils/FlatBuffersUtils.swift b/submodules/TelegramCore/Sources/Utils/FlatBuffersUtils.swift index 98d4e89bc1..af60f0072b 100644 --- a/submodules/TelegramCore/Sources/Utils/FlatBuffersUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/FlatBuffersUtils.swift @@ -52,3 +52,13 @@ public extension PixelDimensions { return TelegramCore_PixelDimensions(width: self.width, height: self.height) } } + +public extension ItemCollectionId { + init(_ id: TelegramCore_ItemCollectionId) { + self.init(namespace: id.namespace, id: id.id) + } + + func asFlatBuffersObject() -> TelegramCore_ItemCollectionId { + return TelegramCore_ItemCollectionId(namespace: self.namespace, id: self.id) + } +} diff --git a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift index 7a4accac0c..c94667f4e7 100644 --- a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift +++ b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift @@ -556,7 +556,7 @@ final class AvatarEditorScreenComponent: Component { if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break @@ -691,7 +691,7 @@ final class AvatarEditorScreenComponent: Component { if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift index fd998f651e..ec987e7b89 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift @@ -546,7 +546,11 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat public func updatePeer(peer: Peer) { if let previousPeer = self.peer, previousPeer.nameColor != peer.nameColor { self.peer = peer - self.avatarNode.setPeer(context: self.context, theme: self.presentationData.theme.theme, peer: EnginePeer(peer), authorOfMessage: self.messageReference, overrideImage: nil, emptyColor: .black, synchronousLoad: false, displayDimensions: CGSize(width: 38.0, height: 38.0)) + if peer.smallProfileImage != nil { + self.avatarNode.setPeerV2(context: self.context, theme: self.presentationData.theme.theme, peer: EnginePeer(peer), authorOfMessage: self.messageReference, overrideImage: nil, emptyColor: .black, synchronousLoad: false, displayDimensions: CGSize(width: 38.0, height: 38.0)) + } else { + self.avatarNode.setPeer(context: self.context, theme: self.presentationData.theme.theme, peer: EnginePeer(peer), authorOfMessage: self.messageReference, overrideImage: nil, emptyColor: .black, synchronousLoad: false, displayDimensions: CGSize(width: 38.0, height: 38.0)) + } } } @@ -561,7 +565,11 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat if peer.isDeleted { overrideImage = .deletedIcon } - self.avatarNode.setPeer(context: context, theme: theme, peer: EnginePeer(peer), authorOfMessage: authorOfMessage, overrideImage: overrideImage, emptyColor: emptyColor, synchronousLoad: synchronousLoad, displayDimensions: CGSize(width: 38.0, height: 38.0)) + if peer.smallProfileImage != nil { + self.avatarNode.setPeerV2(context: context, theme: theme, peer: EnginePeer(peer), authorOfMessage: authorOfMessage, overrideImage: overrideImage, emptyColor: emptyColor, synchronousLoad: synchronousLoad, displayDimensions: CGSize(width: 38.0, height: 38.0)) + } else { + self.avatarNode.setPeer(context: context, theme: theme, peer: EnginePeer(peer), authorOfMessage: authorOfMessage, overrideImage: overrideImage, emptyColor: emptyColor, synchronousLoad: synchronousLoad, displayDimensions: CGSize(width: 38.0, height: 38.0)) + } if peer.isPremium && context.sharedContext.energyUsageSettings.autoplayVideo { self.cachedDataDisposable.set((context.account.postbox.peerView(id: peer.id) diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift index 5a40912d80..6852b760cb 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift @@ -787,7 +787,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { if let strongSelf = self { strongSelf.scheduledContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId, scrollToGroup: scrollToGroup)) } - let _ = context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start() + let _ = context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info._parse(), items: featuredEmojiPack.topItems).start() break } @@ -1300,7 +1300,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift index 7d65cbe842..f67543bd15 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift @@ -95,7 +95,7 @@ private enum StickerSearchEntry: Identifiable, Comparable { case let .global(_, info, topItems, installed, topSeparator): let itemContext = StickerPaneSearchGlobalItemContext() itemContext.canPlayMedia = true - return StickerPaneSearchGlobalItem(context: context, theme: theme, strings: strings, listAppearance: false, info: info, topItems: topItems, topSeparator: topSeparator, regularInsets: false, installed: installed, unread: false, open: { + return StickerPaneSearchGlobalItem(context: context, theme: theme, strings: strings, listAppearance: false, info: StickerPackCollectionInfo.Accessor(info), topItems: topItems, topSeparator: topSeparator, regularInsets: false, installed: installed, unread: false, open: { interaction.open(info) }, install: { interaction.install(info, topItems, !installed) @@ -255,10 +255,11 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode { |> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in switch result { case let .result(info, items, installed): + let info = info._parse() if installed { return .complete() } else { - return preloadedStickerPackThumbnail(account: context.account, info: info, items: items) + return preloadedStickerPackThumbnail(account: context.account, info: StickerPackCollectionInfo.Accessor(info), items: items) |> filter { $0 } |> ignoreValues |> then( diff --git a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift index 984f2791f9..9728c603d0 100644 --- a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift @@ -452,7 +452,7 @@ public final class EmojiStatusSelectionController: ViewController { if let strongSelf = self { strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId, scrollToGroup: true)) } - let _ = strongSelf.context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start() + let _ = strongSelf.context.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info._parse(), items: featuredEmojiPack.topItems).start() break } diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index f997809448..6811ddf78d 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -62,12 +62,15 @@ public final class EntityKeyboardAnimationData: Equatable { public enum Resource: Equatable { case resource(MediaResourceReference) + case stickerPackThumbnail(id: Int64, accessHash: Int64, info: StickerPackCollectionInfo.Accessor) case file(PartialMediaReference?, TelegramMediaFile.Accessor) func _parse() -> MediaResourceReference { switch self { case let .resource(resource): return resource + case let .stickerPackThumbnail(id, accessHash, info): + return .stickerPackThumbnail(stickerPack: .id(id: id, accessHash: accessHash), resource: info._parse().thumbnail!.resource) case let .file(partialReference, file): let file = file._parse() if let partialReference { diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentSignals.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentSignals.swift index 670e715d85..e5631ac485 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentSignals.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentSignals.swift @@ -73,7 +73,7 @@ public extension EmojiPagerContentComponent { let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings struct PeerSpecificPackData: Equatable { - var info: StickerPackCollectionInfo + var info: StickerPackCollectionInfo.Accessor var items: [StickerPackItem] var peer: EnginePeer @@ -282,7 +282,7 @@ public extension EmojiPagerContentComponent { let animationData: EntityKeyboardAnimationData - if let thumbnail = featuredEmojiPack.info.thumbnail { + if let thumbnailDimensions = featuredEmojiPack.info.thumbnailDimensions { let type: EntityKeyboardAnimationData.ItemType if item.file.isAnimatedSticker { type = .lottie @@ -295,8 +295,8 @@ public extension EmojiPagerContentComponent { animationData = EntityKeyboardAnimationData( id: .stickerPackThumbnail(featuredEmojiPack.info.id), type: type, - resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: featuredEmojiPack.info.id.id, accessHash: featuredEmojiPack.info.accessHash), resource: thumbnail.resource)), - dimensions: thumbnail.dimensions.cgSize, + resource: .stickerPackThumbnail(id: featuredEmojiPack.info.id.id, accessHash: featuredEmojiPack.info.accessHash, info: featuredEmojiPack.info), + dimensions: thumbnailDimensions.cgSize, immediateThumbnailData: featuredEmojiPack.info.immediateThumbnailData, isReaction: false, isTemplate: false @@ -1471,7 +1471,7 @@ public extension EmojiPagerContentComponent { var headerItem: EntityKeyboardAnimationData? if let thumbnailFileId = featuredEmojiPack.info.thumbnailFileId, let file = featuredEmojiPack.topItems.first(where: { $0.file.fileId.id == thumbnailFileId }) { headerItem = EntityKeyboardAnimationData(file: file.file) - } else if let thumbnail = featuredEmojiPack.info.thumbnail { + } else if let thumbnailDimensions = featuredEmojiPack.info.thumbnailDimensions { let info = featuredEmojiPack.info let type: EntityKeyboardAnimationData.ItemType if item.file.isAnimatedSticker { @@ -1485,8 +1485,8 @@ public extension EmojiPagerContentComponent { headerItem = EntityKeyboardAnimationData( id: .stickerPackThumbnail(info.id), type: type, - resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)), - dimensions: thumbnail.dimensions.cgSize, + resource: .stickerPackThumbnail(id: featuredEmojiPack.info.id.id, accessHash: featuredEmojiPack.info.accessHash, info: featuredEmojiPack.info), + dimensions: thumbnailDimensions.cgSize, immediateThumbnailData: info.immediateThumbnailData, isReaction: false, isTemplate: false @@ -1632,7 +1632,7 @@ public extension EmojiPagerContentComponent { let isPremiumDisabled = premiumConfiguration.isPremiumDisabled struct PeerSpecificPackData: Equatable { - var info: StickerPackCollectionInfo + var info: StickerPackCollectionInfo.Accessor var items: [StickerPackItem] var peer: EnginePeer @@ -1769,7 +1769,7 @@ public extension EmojiPagerContentComponent { let animationData: EntityKeyboardAnimationData - if let thumbnail = featuredStickerPack.info.thumbnail { + if let thumbnailDimensions = featuredStickerPack.info.thumbnailDimensions { let type: EntityKeyboardAnimationData.ItemType if item.file.isAnimatedSticker { type = .lottie @@ -1782,8 +1782,8 @@ public extension EmojiPagerContentComponent { animationData = EntityKeyboardAnimationData( id: .stickerPackThumbnail(featuredStickerPack.info.id), type: type, - resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash), resource: thumbnail.resource)), - dimensions: thumbnail.dimensions.cgSize, + resource: .stickerPackThumbnail(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash, info: featuredStickerPack.info), + dimensions: thumbnailDimensions.cgSize, immediateThumbnailData: featuredStickerPack.info.immediateThumbnailData, isReaction: false, isTemplate: false @@ -2084,7 +2084,7 @@ public extension EmojiPagerContentComponent { if let thumbnailFileId = featuredStickerPack.info.thumbnailFileId, let file = featuredStickerPack.topItems.first(where: { $0.file.fileId.id == thumbnailFileId }) { headerItem = EntityKeyboardAnimationData(file: file.file) - } else if let thumbnail = featuredStickerPack.info.thumbnail { + } else if let thumbnailDimensions = featuredStickerPack.info.thumbnailDimensions { let info = featuredStickerPack.info let type: EntityKeyboardAnimationData.ItemType if item.file.isAnimatedSticker { @@ -2098,8 +2098,8 @@ public extension EmojiPagerContentComponent { headerItem = EntityKeyboardAnimationData( id: .stickerPackThumbnail(info.id), type: type, - resource: .resource(.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)), - dimensions: thumbnail.dimensions.cgSize, + resource: .stickerPackThumbnail(id: info.id.id, accessHash: info.accessHash, info: info), + dimensions: thumbnailDimensions.cgSize, immediateThumbnailData: info.immediateThumbnailData, isReaction: false, isTemplate: false diff --git a/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift b/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift index ffb5fa4e49..bf412d075f 100644 --- a/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift +++ b/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift @@ -910,7 +910,7 @@ private final class ForumCreateTopicScreenComponent: CombinedComponent { } for featuredEmojiPack in view.items.lazy.map({ $0.contents.get(FeaturedStickerPackItem.self)! }) { if featuredEmojiPack.info.id == collectionId { - let _ = accountContext.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start() + let _ = accountContext.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info._parse(), items: featuredEmojiPack.topItems).start() break } diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackSetupController.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackSetupController.swift index d9f1f2c561..87b9e28665 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackSetupController.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackSetupController.swift @@ -220,7 +220,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry { case let .packsTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .pack(_, _, _, info, topItem, count, playAnimatedStickers, selected): - return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: StickerPackCollectionInfo.Accessor(info), itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { if selected { arguments.openStickerPack(info) } else { @@ -337,7 +337,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres case .fetching: return nil case let .result(info, items, _): - return InitialStickerPackData.data(StickerPackData(info: info, item: items.first)) + return InitialStickerPackData.data(StickerPackData(info: info._parse(), item: items.first)) } }) } else { @@ -389,7 +389,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres case .none: return .single((searchText, .notFound)) case let .result(info, items, _): - return .single((searchText, .found(StickerPackData(info: info, item: items.first)))) + return .single((searchText, .found(StickerPackData(info: info._parse(), item: items.first)))) } } |> afterNext { value in diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift index 89ea9480b3..29f9b0d3c6 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift @@ -48,7 +48,7 @@ private final class GroupStickerSearchEntry: Comparable, Identifiable { let pack = self.pack let count = presentationData.strings.StickerPack_EmojiCount(pack.count) - return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), context: context, packInfo: pack, itemCount: count, topItem: self.topItem as? StickerPackItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, style: .plain, sectionId: 0, action: { + return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), context: context, packInfo: StickerPackCollectionInfo.Accessor(pack), itemCount: count, topItem: self.topItem as? StickerPackItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, style: .plain, sectionId: 0, action: { interaction.packSelected(pack) }, setPackIdWithRevealedOptions: { _, _ in }, addPack: { diff --git a/submodules/TelegramUI/Components/StickerPickerScreen/Sources/StickerPickerScreen.swift b/submodules/TelegramUI/Components/StickerPickerScreen/Sources/StickerPickerScreen.swift index 428b2d03d8..6968c89459 100644 --- a/submodules/TelegramUI/Components/StickerPickerScreen/Sources/StickerPickerScreen.swift +++ b/submodules/TelegramUI/Components/StickerPickerScreen/Sources/StickerPickerScreen.swift @@ -955,7 +955,7 @@ public class StickerPickerScreen: ViewController { if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break @@ -1370,7 +1370,7 @@ public class StickerPickerScreen: ViewController { if installed { return .complete() } else { - return context.engine.stickers.addStickerPackInteractively(info: info, items: items) + return context.engine.stickers.addStickerPackInteractively(info: info._parse(), items: items) } case .fetching: break diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index f6d074fba6..29f6e34a44 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -1901,6 +1901,14 @@ private func extractAccountManagerState(records: AccountRecordsView take(1) + |> deliverOnMainQueue).start(next: { activeAccounts in + for (_, context, _) in activeAccounts.accounts { + context.account.postbox.clearCaches() + } + }) }) self.isInForegroundValue = false diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index b850055003..3913193b89 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -552,7 +552,6 @@ extension ChatControllerImpl { return .single(true) } else { return .single(false) - |> delay(0.1, queue: .mainQueue()) } } |> distinctUntilChanged @@ -717,15 +716,15 @@ extension ChatControllerImpl { } ) - self.cachedDataDisposable = combineLatest(queue: .mainQueue(), self.chatDisplayNode.historyNode.cachedPeerDataAndMessages, - hasPendingMessages, - isTopReplyThreadMessageShown, - topPinnedMessage, - customEmojiAvailable, - isForum, - threadData, - forumTopicData, - premiumGiftOptions + self.cachedDataDisposable = combineLatest(queue: .mainQueue(), self.chatDisplayNode.historyNode.cachedPeerDataAndMessages |> debug_measureTimeToFirstEvent(label: "cachedData_cachedPeerDataAndMessages"), + hasPendingMessages |> debug_measureTimeToFirstEvent(label: "cachedData_hasPendingMessages"), + isTopReplyThreadMessageShown |> debug_measureTimeToFirstEvent(label: "cachedData_isTopReplyThreadMessageShown"), + topPinnedMessage |> debug_measureTimeToFirstEvent(label: "cachedData_topPinnedMessage"), + customEmojiAvailable |> debug_measureTimeToFirstEvent(label: "cachedData_customEmojiAvailable"), + isForum |> debug_measureTimeToFirstEvent(label: "cachedData_isForum"), + threadData |> debug_measureTimeToFirstEvent(label: "cachedData_threadData"), + forumTopicData |> debug_measureTimeToFirstEvent(label: "cachedData_forumTopicData"), + premiumGiftOptions |> debug_measureTimeToFirstEvent(label: "cachedData_premiumGiftOptions") ).startStrict(next: { [weak self] cachedDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage, customEmojiAvailable, isForum, threadData, forumTopicData, premiumGiftOptions in if let strongSelf = self { let (cachedData, messages) = cachedDataAndMessages @@ -990,21 +989,26 @@ extension ChatControllerImpl { if case .replyThread = self.chatLocation { effectiveCachedDataReady = self.cachedDataReady.get() } else { - //effectiveCachedDataReady = .single(true) effectiveCachedDataReady = self.cachedDataReady.get() } var measure_isFirstTime = true let initTimestamp = self.initTimestamp + + let mapped_chatLocationInfoReady = self._chatLocationInfoReady.get() |> filter { $0 } |> debug_measureTimeToFirstEvent(label: "chatLocationInfoReady") + let mapped_effectiveCachedDataReady = effectiveCachedDataReady |> filter { $0 } |> debug_measureTimeToFirstEvent(label: "effectiveCachedDataReady") + let mapped_initialDataReady = initialData |> map { $0 != nil } |> filter { $0 } |> debug_measureTimeToFirstEvent(label: "initialDataReady") + let mapped_wallpaperReady = self.wallpaperReady.get() |> filter { $0 } |> debug_measureTimeToFirstEvent(label: "wallpaperReady") + let mapped_presentationReady = self.presentationReady.get() |> filter { $0 } |> debug_measureTimeToFirstEvent(label: "presentationReady") + self.ready.set(combineLatest(queue: .mainQueue(), - self.chatDisplayNode.historyNode.historyState.get(), - self._chatLocationInfoReady.get(), - effectiveCachedDataReady, - initialData, - self.wallpaperReady.get(), - self.presentationReady.get() + mapped_chatLocationInfoReady, + mapped_effectiveCachedDataReady, + mapped_initialDataReady, + mapped_wallpaperReady, + mapped_presentationReady ) - |> map { _, chatLocationInfoReady, cachedDataReady, _, wallpaperReady, presentationReady in - return chatLocationInfoReady && cachedDataReady && wallpaperReady && presentationReady + |> map { chatLocationInfoReady, cachedDataReady, initialData, wallpaperReady, presentationReady in + return chatLocationInfoReady && cachedDataReady && initialData && wallpaperReady && presentationReady } |> distinctUntilChanged |> beforeNext { value in @@ -1016,6 +1020,9 @@ extension ChatControllerImpl { #endif } }) + #if DEBUG + //self.ready.set(.single(true)) + #endif if self.context.sharedContext.immediateExperimentalUISettings.crashOnLongQueries { let _ = (self.ready.get() diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index a8ff8c8120..0931bae652 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1720,8 +1720,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto let startTime = CFAbsoluteTimeGetCurrent() var measure_isFirstTime = true let messageViewQueue = Queue.mainQueue() - let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue, - historyViewUpdate, + let historyViewTransitionDisposable = (combineLatest(queue: messageViewQueue, + historyViewUpdate |> debug_measureTimeToFirstEvent(label: "historyViewUpdate"), self.chatPresentationDataPromise.get(), selectedMessages, updatingMedia, @@ -1746,7 +1746,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto chatThemes, deviceContactsNumbers, contentSettings - ).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings in + ) |> debug_measureTimeToFirstEvent(label: "firstChatHistoryTransition")).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings in let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots, allAdMessages) = promises if measure_isFirstTime { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 538d0f5eee..e516970a28 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -2853,7 +2853,7 @@ private final class ChatReadReportContextItemNode: ASDisplayNode, ContextMenuCus } |> map { result -> StickerPackCollectionInfo? in if case let .result(info, _, _) = result { - return info + return info._parse() } else { return nil }