mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Drawing
This commit is contained in:
@@ -40,6 +40,7 @@ swift_library(
|
||||
"//submodules/Components/SolidRoundedButtonComponent:SolidRoundedButtonComponent",
|
||||
"//submodules/Components/LottieAnimationComponent:LottieAnimationComponent",
|
||||
"//submodules/LocalizedPeerData:LocalizedPeerData",
|
||||
"//submodules/TelegramNotices:TelegramNotices",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@@ -23,6 +23,7 @@ import AudioToolbox
|
||||
import SolidRoundedButtonComponent
|
||||
import EmojiTextAttachmentView
|
||||
import EmojiStatusComponent
|
||||
import TelegramNotices
|
||||
|
||||
private let premiumBadgeIcon: UIImage? = generateTintedImage(image: UIImage(bundleImageName: "Chat List/PeerPremiumIcon"), color: .white)
|
||||
private let featuredBadgeIcon: UIImage? = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/PanelBadgeAdd"), color: .white)
|
||||
@@ -7059,6 +7060,469 @@ public final class EmojiPagerContentComponent: Component {
|
||||
}
|
||||
return emojiItems
|
||||
}
|
||||
|
||||
public static func stickerInputData(
|
||||
context: AccountContext,
|
||||
animationCache: AnimationCache,
|
||||
animationRenderer: MultiAnimationRenderer,
|
||||
stickerNamespaces: [ItemCollectionId.Namespace],
|
||||
stickerOrderedItemListCollectionIds: [Int32],
|
||||
chatPeerId: EnginePeer.Id?
|
||||
) -> Signal<EmojiPagerContentComponent, NoError> {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let isPremiumDisabled = premiumConfiguration.isPremiumDisabled
|
||||
|
||||
struct PeerSpecificPackData: Equatable {
|
||||
var info: StickerPackCollectionInfo
|
||||
var items: [StickerPackItem]
|
||||
var peer: EnginePeer
|
||||
|
||||
static func ==(lhs: PeerSpecificPackData, rhs: PeerSpecificPackData) -> Bool {
|
||||
if lhs.info.id != rhs.info.id {
|
||||
return false
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let peerSpecificPack: Signal<PeerSpecificPackData?, NoError>
|
||||
if let chatPeerId = chatPeerId {
|
||||
peerSpecificPack = combineLatest(
|
||||
context.engine.peers.peerSpecificStickerPack(peerId: chatPeerId),
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: chatPeerId))
|
||||
)
|
||||
|> map { packData, peer -> PeerSpecificPackData? in
|
||||
guard let peer = peer else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let (info, items) = packData.packInfo else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return PeerSpecificPackData(info: info, items: items.compactMap { $0 as? StickerPackItem }, peer: peer)
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
} else {
|
||||
peerSpecificPack = .single(nil)
|
||||
}
|
||||
|
||||
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
|
||||
|
||||
return combineLatest(
|
||||
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: stickerOrderedItemListCollectionIds, namespaces: stickerNamespaces, aroundIndex: nil, count: 10000000),
|
||||
hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: false),
|
||||
context.account.viewTracker.featuredStickerPacks(),
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: Namespaces.CachedItemCollection.featuredStickersConfiguration, id: ValueBoxKey(length: 0))),
|
||||
ApplicationSpecificNotice.dismissedTrendingStickerPacks(accountManager: context.sharedContext.accountManager),
|
||||
peerSpecificPack
|
||||
)
|
||||
|> map { view, hasPremium, featuredStickerPacks, featuredStickersConfiguration, dismissedTrendingStickerPacks, peerSpecificPack -> EmojiPagerContentComponent in
|
||||
struct ItemGroup {
|
||||
var supergroupId: AnyHashable
|
||||
var id: AnyHashable
|
||||
var title: String
|
||||
var subtitle: String?
|
||||
var actionButtonTitle: String?
|
||||
var isPremiumLocked: Bool
|
||||
var isFeatured: Bool
|
||||
var displayPremiumBadges: Bool
|
||||
var headerItem: EntityKeyboardAnimationData?
|
||||
var items: [EmojiPagerContentComponent.Item]
|
||||
}
|
||||
var itemGroups: [ItemGroup] = []
|
||||
var itemGroupIndexById: [AnyHashable: Int] = [:]
|
||||
|
||||
var savedStickers: OrderedItemListView?
|
||||
var recentStickers: OrderedItemListView?
|
||||
var cloudPremiumStickers: OrderedItemListView?
|
||||
for orderedView in view.orderedItemListsViews {
|
||||
if orderedView.collectionId == Namespaces.OrderedItemList.CloudRecentStickers {
|
||||
recentStickers = orderedView
|
||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudSavedStickers {
|
||||
savedStickers = orderedView
|
||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudAllPremiumStickers {
|
||||
cloudPremiumStickers = orderedView
|
||||
}
|
||||
}
|
||||
|
||||
var installedCollectionIds = Set<ItemCollectionId>()
|
||||
for (id, _, _) in view.collectionInfos {
|
||||
installedCollectionIds.insert(id)
|
||||
}
|
||||
|
||||
let dismissedTrendingStickerPacksSet = Set(dismissedTrendingStickerPacks ?? [])
|
||||
let featuredStickerPacksSet = Set(featuredStickerPacks.map(\.info.id.id))
|
||||
|
||||
if dismissedTrendingStickerPacksSet != featuredStickerPacksSet {
|
||||
let featuredStickersConfiguration = featuredStickersConfiguration?.get(FeaturedStickersConfiguration.self)
|
||||
for featuredStickerPack in featuredStickerPacks {
|
||||
if installedCollectionIds.contains(featuredStickerPack.info.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
guard let item = featuredStickerPack.topItems.first else {
|
||||
continue
|
||||
}
|
||||
|
||||
let animationData: EntityKeyboardAnimationData
|
||||
|
||||
if let thumbnail = featuredStickerPack.info.thumbnail {
|
||||
let type: EntityKeyboardAnimationData.ItemType
|
||||
if item.file.isAnimatedSticker {
|
||||
type = .lottie
|
||||
} else if item.file.isVideoEmoji || item.file.isVideoSticker {
|
||||
type = .video
|
||||
} else {
|
||||
type = .still
|
||||
}
|
||||
|
||||
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),
|
||||
dimensions: thumbnail.dimensions.cgSize,
|
||||
immediateThumbnailData: featuredStickerPack.info.immediateThumbnailData,
|
||||
isReaction: false
|
||||
)
|
||||
} else {
|
||||
animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
}
|
||||
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let supergroupId = "featuredTop"
|
||||
let groupId: AnyHashable = supergroupId
|
||||
let isPremiumLocked: Bool = item.file.isPremiumSticker && !hasPremium
|
||||
if isPremiumLocked && isPremiumDisabled {
|
||||
continue
|
||||
}
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
|
||||
let trendingIsPremium = featuredStickersConfiguration?.isPremium ?? false
|
||||
let title = trendingIsPremium ? strings.Stickers_TrendingPremiumStickers : strings.StickerPacksSettings_FeaturedPacks
|
||||
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: title, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let savedStickers = savedStickers {
|
||||
for item in savedStickers.items {
|
||||
guard let item = item.contents.get(SavedStickerItem.self) else {
|
||||
continue
|
||||
}
|
||||
if isPremiumDisabled && item.file.isPremiumSticker {
|
||||
continue
|
||||
}
|
||||
|
||||
let animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let groupId = "saved"
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.EmojiInput_SectionTitleFavoriteStickers, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let recentStickers = recentStickers {
|
||||
for item in recentStickers.items {
|
||||
guard let item = item.contents.get(RecentMediaItem.self) else {
|
||||
continue
|
||||
}
|
||||
if isPremiumDisabled && item.media.isPremiumSticker {
|
||||
continue
|
||||
}
|
||||
|
||||
let animationData = EntityKeyboardAnimationData(file: item.media)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.media,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let groupId = "recent"
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.Stickers_FrequentlyUsed, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var premiumStickers: [StickerPackItem] = []
|
||||
if hasPremium {
|
||||
for entry in view.entries {
|
||||
guard let item = entry.item as? StickerPackItem else {
|
||||
continue
|
||||
}
|
||||
|
||||
if item.file.isPremiumSticker {
|
||||
premiumStickers.append(item)
|
||||
}
|
||||
}
|
||||
|
||||
if let cloudPremiumStickers = cloudPremiumStickers, !cloudPremiumStickers.items.isEmpty {
|
||||
premiumStickers.append(contentsOf: cloudPremiumStickers.items.compactMap { item -> StickerPackItem? in guard let item = item.contents.get(RecentMediaItem.self) else {
|
||||
return nil
|
||||
}
|
||||
return StickerPackItem(index: ItemCollectionItemIndex(index: 0, id: 0), file: item.media, indexKeys: [])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if !premiumStickers.isEmpty {
|
||||
var processedIds = Set<MediaId>()
|
||||
for item in premiumStickers {
|
||||
if isPremiumDisabled && item.file.isPremiumSticker {
|
||||
continue
|
||||
}
|
||||
if processedIds.contains(item.file.fileId) {
|
||||
continue
|
||||
}
|
||||
processedIds.insert(item.file.fileId)
|
||||
|
||||
let animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let groupId = "premium"
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: strings.EmojiInput_SectionTitlePremiumStickers, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var avatarPeer: EnginePeer?
|
||||
if let peerSpecificPack = peerSpecificPack {
|
||||
avatarPeer = peerSpecificPack.peer
|
||||
|
||||
var processedIds = Set<MediaId>()
|
||||
for item in peerSpecificPack.items {
|
||||
if isPremiumDisabled && item.file.isPremiumSticker {
|
||||
continue
|
||||
}
|
||||
if processedIds.contains(item.file.fileId) {
|
||||
continue
|
||||
}
|
||||
processedIds.insert(item.file.fileId)
|
||||
|
||||
let animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let groupId = "peerSpecific"
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: peerSpecificPack.peer.compactDisplayTitle, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: false, headerItem: nil, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for entry in view.entries {
|
||||
guard let item = entry.item as? StickerPackItem else {
|
||||
continue
|
||||
}
|
||||
let animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
let groupId = entry.index.collectionId
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
|
||||
var title = ""
|
||||
var headerItem: EntityKeyboardAnimationData?
|
||||
inner: for (id, info, _) in view.collectionInfos {
|
||||
if id == groupId, let info = info as? StickerPackCollectionInfo {
|
||||
title = info.title
|
||||
|
||||
if let thumbnail = info.thumbnail {
|
||||
let type: EntityKeyboardAnimationData.ItemType
|
||||
if item.file.isAnimatedSticker {
|
||||
type = .lottie
|
||||
} else if item.file.isVideoEmoji || item.file.isVideoSticker {
|
||||
type = .video
|
||||
} else {
|
||||
type = .still
|
||||
}
|
||||
|
||||
headerItem = EntityKeyboardAnimationData(
|
||||
id: .stickerPackThumbnail(info.id),
|
||||
type: type,
|
||||
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
|
||||
dimensions: thumbnail.dimensions.cgSize,
|
||||
immediateThumbnailData: info.immediateThumbnailData,
|
||||
isReaction: false
|
||||
)
|
||||
}
|
||||
|
||||
break inner
|
||||
}
|
||||
}
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: title, subtitle: nil, actionButtonTitle: nil, isPremiumLocked: false, isFeatured: false, displayPremiumBadges: true, headerItem: headerItem, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
|
||||
for featuredStickerPack in featuredStickerPacks {
|
||||
if installedCollectionIds.contains(featuredStickerPack.info.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
for item in featuredStickerPack.topItems {
|
||||
let animationData = EntityKeyboardAnimationData(file: item.file)
|
||||
let resultItem = EmojiPagerContentComponent.Item(
|
||||
animationData: animationData,
|
||||
content: .animation(animationData),
|
||||
itemFile: item.file,
|
||||
subgroupId: nil,
|
||||
icon: .none,
|
||||
accentTint: false
|
||||
)
|
||||
|
||||
let supergroupId = featuredStickerPack.info.id
|
||||
let groupId: AnyHashable = supergroupId
|
||||
let isPremiumLocked: Bool = item.file.isPremiumSticker && !hasPremium
|
||||
if isPremiumLocked && isPremiumDisabled {
|
||||
continue
|
||||
}
|
||||
if let groupIndex = itemGroupIndexById[groupId] {
|
||||
itemGroups[groupIndex].items.append(resultItem)
|
||||
} else {
|
||||
itemGroupIndexById[groupId] = itemGroups.count
|
||||
|
||||
let subtitle: String = strings.StickerPack_StickerCount(Int32(featuredStickerPack.info.count))
|
||||
var headerItem: EntityKeyboardAnimationData?
|
||||
|
||||
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 {
|
||||
let info = featuredStickerPack.info
|
||||
let type: EntityKeyboardAnimationData.ItemType
|
||||
if item.file.isAnimatedSticker {
|
||||
type = .lottie
|
||||
} else if item.file.isVideoEmoji || item.file.isVideoSticker {
|
||||
type = .video
|
||||
} else {
|
||||
type = .still
|
||||
}
|
||||
|
||||
headerItem = EntityKeyboardAnimationData(
|
||||
id: .stickerPackThumbnail(info.id),
|
||||
type: type,
|
||||
resource: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource),
|
||||
dimensions: thumbnail.dimensions.cgSize,
|
||||
immediateThumbnailData: info.immediateThumbnailData,
|
||||
isReaction: false
|
||||
)
|
||||
}
|
||||
|
||||
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: featuredStickerPack.info.title, subtitle: subtitle, actionButtonTitle: strings.Stickers_Install, isPremiumLocked: isPremiumLocked, isFeatured: true, displayPremiumBadges: false, headerItem: headerItem, items: [resultItem]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EmojiPagerContentComponent(
|
||||
id: "stickers",
|
||||
context: context,
|
||||
avatarPeer: avatarPeer,
|
||||
animationCache: animationCache,
|
||||
animationRenderer: animationRenderer,
|
||||
inputInteractionHolder: EmojiPagerContentComponent.InputInteractionHolder(),
|
||||
itemGroups: itemGroups.map { group -> EmojiPagerContentComponent.ItemGroup in
|
||||
var hasClear = false
|
||||
var isEmbedded = false
|
||||
if group.id == AnyHashable("recent") {
|
||||
hasClear = true
|
||||
} else if group.id == AnyHashable("featuredTop") {
|
||||
hasClear = true
|
||||
isEmbedded = true
|
||||
}
|
||||
|
||||
return EmojiPagerContentComponent.ItemGroup(
|
||||
supergroupId: group.supergroupId,
|
||||
groupId: group.id,
|
||||
title: group.title,
|
||||
subtitle: group.subtitle,
|
||||
actionButtonTitle: group.actionButtonTitle,
|
||||
isFeatured: group.isFeatured,
|
||||
isPremiumLocked: group.isPremiumLocked,
|
||||
isEmbedded: isEmbedded,
|
||||
hasClear: hasClear,
|
||||
collapsedLineCount: nil,
|
||||
displayPremiumBadges: group.displayPremiumBadges,
|
||||
headerItem: group.headerItem,
|
||||
items: group.items
|
||||
)
|
||||
},
|
||||
itemLayoutType: .detailed,
|
||||
itemContentUniqueId: nil,
|
||||
warpContentsOnEdges: false,
|
||||
displaySearchWithPlaceholder: nil,
|
||||
searchInitiallyHidden: false,
|
||||
searchIsPlaceholderOnly: true,
|
||||
emptySearchResults: nil,
|
||||
enableLongPress: false,
|
||||
selectedItems: Set()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generateTopicIcon(backgroundColors: [UIColor], strokeColors: [UIColor], title: String) -> UIImage? {
|
||||
|
||||
@@ -90,7 +90,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
public let isContentInFocus: Bool
|
||||
public let containerInsets: UIEdgeInsets
|
||||
public let topPanelInsets: UIEdgeInsets
|
||||
public let emojiContent: EmojiPagerContentComponent
|
||||
public let emojiContent: EmojiPagerContentComponent?
|
||||
public let stickerContent: EmojiPagerContentComponent?
|
||||
public let gifContent: GifPagerContentComponent?
|
||||
public let hasRecentGifs: Bool
|
||||
@@ -116,7 +116,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
isContentInFocus: Bool,
|
||||
containerInsets: UIEdgeInsets,
|
||||
topPanelInsets: UIEdgeInsets,
|
||||
emojiContent: EmojiPagerContentComponent,
|
||||
emojiContent: EmojiPagerContentComponent?,
|
||||
stickerContent: EmojiPagerContentComponent?,
|
||||
gifContent: GifPagerContentComponent?,
|
||||
hasRecentGifs: Bool,
|
||||
@@ -304,24 +304,26 @@ public final class EntityKeyboardComponent: Component {
|
||||
}
|
||||
))
|
||||
))
|
||||
for emoji in component.availableGifSearchEmojies {
|
||||
topGifItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: emoji.emoji,
|
||||
isReorderable: false,
|
||||
content: AnyComponent(EntityKeyboardAnimationTopPanelComponent(
|
||||
context: component.emojiContent.context,
|
||||
item: EntityKeyboardAnimationData(file: emoji.file),
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
animationCache: component.emojiContent.animationCache,
|
||||
animationRenderer: component.emojiContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: emoji.title,
|
||||
pressed: { [weak self] in
|
||||
self?.component?.switchToGifSubject(.emojiSearch(emoji.emoji))
|
||||
}
|
||||
if let emojiContent = component.emojiContent {
|
||||
for emoji in component.availableGifSearchEmojies {
|
||||
topGifItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: emoji.emoji,
|
||||
isReorderable: false,
|
||||
content: AnyComponent(EntityKeyboardAnimationTopPanelComponent(
|
||||
context: emojiContent.context,
|
||||
item: EntityKeyboardAnimationData(file: emoji.file),
|
||||
isFeatured: false,
|
||||
isPremiumLocked: false,
|
||||
animationCache: emojiContent.animationCache,
|
||||
animationRenderer: emojiContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: emoji.title,
|
||||
pressed: { [weak self] in
|
||||
self?.component?.switchToGifSubject(.emojiSearch(emoji.emoji))
|
||||
}
|
||||
))
|
||||
))
|
||||
))
|
||||
}
|
||||
}
|
||||
let defaultActiveGifItemId: AnyHashable
|
||||
switch gifContent.subject {
|
||||
@@ -480,101 +482,104 @@ public final class EntityKeyboardComponent: Component {
|
||||
}
|
||||
|
||||
let emojiContentItemIdUpdated = ActionSlot<(AnyHashable, AnyHashable?, Transition)>()
|
||||
contents.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(component.emojiContent)))
|
||||
var topEmojiItems: [EntityKeyboardTopPanelComponent.Item] = []
|
||||
for itemGroup in component.emojiContent.itemGroups {
|
||||
if !itemGroup.items.isEmpty {
|
||||
if let id = itemGroup.groupId.base as? String {
|
||||
if id == "recent" {
|
||||
let iconMapping: [String: EntityKeyboardIconTopPanelComponent.Icon] = [
|
||||
"recent": .recent,
|
||||
]
|
||||
let titleMapping: [String: String] = [
|
||||
"recent": component.strings.Stickers_Recent,
|
||||
]
|
||||
if let icon = iconMapping[id], let title = titleMapping[id] {
|
||||
if let emojiContent = component.emojiContent {
|
||||
contents.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(emojiContent)))
|
||||
var topEmojiItems: [EntityKeyboardTopPanelComponent.Item] = []
|
||||
for itemGroup in emojiContent.itemGroups {
|
||||
if !itemGroup.items.isEmpty {
|
||||
if let id = itemGroup.groupId.base as? String {
|
||||
if id == "recent" {
|
||||
let iconMapping: [String: EntityKeyboardIconTopPanelComponent.Icon] = [
|
||||
"recent": .recent,
|
||||
]
|
||||
let titleMapping: [String: String] = [
|
||||
"recent": component.strings.Stickers_Recent,
|
||||
]
|
||||
if let icon = iconMapping[id], let title = titleMapping[id] {
|
||||
topEmojiItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: itemGroup.supergroupId,
|
||||
isReorderable: false,
|
||||
content: AnyComponent(EntityKeyboardIconTopPanelComponent(
|
||||
icon: icon,
|
||||
theme: component.theme,
|
||||
useAccentColor: false,
|
||||
title: title,
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
} else if id == "static" {
|
||||
topEmojiItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: itemGroup.supergroupId,
|
||||
isReorderable: false,
|
||||
content: AnyComponent(EntityKeyboardIconTopPanelComponent(
|
||||
icon: icon,
|
||||
content: AnyComponent(EntityKeyboardStaticStickersPanelComponent(
|
||||
theme: component.theme,
|
||||
useAccentColor: false,
|
||||
title: title,
|
||||
title: component.strings.EmojiInput_PanelTitleEmoji,
|
||||
pressed: { [weak self] subgroupId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: subgroupId.rawValue)
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
} else {
|
||||
if let animationData = itemGroup.items[0].animationData {
|
||||
topEmojiItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: itemGroup.supergroupId,
|
||||
isReorderable: !itemGroup.isFeatured,
|
||||
content: AnyComponent(EntityKeyboardAnimationTopPanelComponent(
|
||||
context: emojiContent.context,
|
||||
item: itemGroup.headerItem ?? animationData,
|
||||
isFeatured: itemGroup.isFeatured,
|
||||
isPremiumLocked: itemGroup.isPremiumLocked,
|
||||
animationCache: emojiContent.animationCache,
|
||||
animationRenderer: emojiContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: itemGroup.title ?? "",
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
} else if id == "static" {
|
||||
topEmojiItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: itemGroup.supergroupId,
|
||||
isReorderable: false,
|
||||
content: AnyComponent(EntityKeyboardStaticStickersPanelComponent(
|
||||
theme: component.theme,
|
||||
title: component.strings.EmojiInput_PanelTitleEmoji,
|
||||
pressed: { [weak self] subgroupId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: subgroupId.rawValue)
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
} else {
|
||||
if let animationData = itemGroup.items[0].animationData {
|
||||
topEmojiItems.append(EntityKeyboardTopPanelComponent.Item(
|
||||
id: itemGroup.supergroupId,
|
||||
isReorderable: !itemGroup.isFeatured,
|
||||
content: AnyComponent(EntityKeyboardAnimationTopPanelComponent(
|
||||
context: component.emojiContent.context,
|
||||
item: itemGroup.headerItem ?? animationData,
|
||||
isFeatured: itemGroup.isFeatured,
|
||||
isPremiumLocked: itemGroup.isPremiumLocked,
|
||||
animationCache: component.emojiContent.animationCache,
|
||||
animationRenderer: component.emojiContent.animationRenderer,
|
||||
theme: component.theme,
|
||||
title: itemGroup.title ?? "",
|
||||
pressed: { [weak self] in
|
||||
self?.scrollToItemGroup(contentId: "emoji", groupId: itemGroup.supergroupId, subgroupId: nil)
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
contentTopPanels.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(EntityKeyboardTopPanelComponent(
|
||||
id: "emoji",
|
||||
theme: component.theme,
|
||||
items: topEmojiItems,
|
||||
containerSideInset: component.containerInsets.left + component.topPanelInsets.left,
|
||||
activeContentItemIdUpdated: emojiContentItemIdUpdated,
|
||||
activeContentItemMapping: ["popular": "recent"],
|
||||
reorderItems: { [weak self] items in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.reorderPacks(category: .emoji, items: items)
|
||||
}
|
||||
))))
|
||||
contentIcons.append(PagerComponentContentIcon(id: "emoji", imageName: "Chat/Input/Media/EntityInputEmojiIcon"))
|
||||
contentAccessoryLeftButtons.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(Button(
|
||||
content: AnyComponent(BundleIconComponent(
|
||||
name: "Chat/Input/Media/EntityInputGlobeIcon",
|
||||
tintColor: component.theme.chat.inputMediaPanel.panelIconColor,
|
||||
maxSize: nil
|
||||
)),
|
||||
action: { [weak self] in
|
||||
guard let strongSelf = self, let component = strongSelf.component else {
|
||||
return
|
||||
}
|
||||
component.switchToTextInput()
|
||||
}
|
||||
).minSize(CGSize(width: 38.0, height: 38.0)))))
|
||||
}
|
||||
contentTopPanels.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(EntityKeyboardTopPanelComponent(
|
||||
id: "emoji",
|
||||
theme: component.theme,
|
||||
items: topEmojiItems,
|
||||
containerSideInset: component.containerInsets.left + component.topPanelInsets.left,
|
||||
activeContentItemIdUpdated: emojiContentItemIdUpdated,
|
||||
activeContentItemMapping: ["popular": "recent"],
|
||||
reorderItems: { [weak self] items in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.reorderPacks(category: .emoji, items: items)
|
||||
}
|
||||
))))
|
||||
contentIcons.append(PagerComponentContentIcon(id: "emoji", imageName: "Chat/Input/Media/EntityInputEmojiIcon"))
|
||||
contentAccessoryLeftButtons.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(Button(
|
||||
content: AnyComponent(BundleIconComponent(
|
||||
name: "Chat/Input/Media/EntityInputGlobeIcon",
|
||||
tintColor: component.theme.chat.inputMediaPanel.panelIconColor,
|
||||
maxSize: nil
|
||||
)),
|
||||
action: { [weak self] in
|
||||
guard let strongSelf = self, let component = strongSelf.component else {
|
||||
return
|
||||
}
|
||||
component.switchToTextInput()
|
||||
}
|
||||
).minSize(CGSize(width: 38.0, height: 38.0)))))
|
||||
let deleteBackwards = component.emojiContent.inputInteractionHolder.inputInteraction?.deleteBackwards
|
||||
|
||||
let deleteBackwards = component.emojiContent?.inputInteractionHolder.inputInteraction?.deleteBackwards
|
||||
contentAccessoryRightButtons.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(Button(
|
||||
content: AnyComponent(BundleIconComponent(
|
||||
name: "Chat/Input/Media/EntityInputClearIcon",
|
||||
@@ -620,7 +625,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
theme: component.theme,
|
||||
containerInsets: component.containerInsets,
|
||||
deleteBackwards: { [weak self] in
|
||||
self?.component?.emojiContent.inputInteractionHolder.inputInteraction?.deleteBackwards()
|
||||
self?.component?.emojiContent?.inputInteractionHolder.inputInteraction?.deleteBackwards()
|
||||
AudioServicesPlaySystemSound(0x451)
|
||||
}
|
||||
)) : nil,
|
||||
@@ -665,7 +670,8 @@ public final class EntityKeyboardComponent: Component {
|
||||
)
|
||||
transition.setFrame(view: self.pagerView, frame: CGRect(origin: CGPoint(), size: pagerSize))
|
||||
|
||||
if let searchComponent = self.searchComponent {
|
||||
let accountContext = component.emojiContent?.context ?? component.stickerContent?.context
|
||||
if let searchComponent = self.searchComponent, let accountContext = accountContext {
|
||||
var animateIn = false
|
||||
let searchView: ComponentHostView<EntitySearchContentEnvironment>
|
||||
var searchViewTransition = transition
|
||||
@@ -686,7 +692,7 @@ public final class EntityKeyboardComponent: Component {
|
||||
component: AnyComponent(searchComponent),
|
||||
environment: {
|
||||
EntitySearchContentEnvironment(
|
||||
context: component.emojiContent.context,
|
||||
context: accountContext,
|
||||
theme: component.theme,
|
||||
deviceMetrics: component.deviceMetrics,
|
||||
inputHeight: component.inputHeight
|
||||
|
||||
Reference in New Issue
Block a user