This commit is contained in:
Ali
2023-01-19 17:50:17 +04:00
parent 7cea72619c
commit dac58e50b3
34 changed files with 2317 additions and 930 deletions

View File

@@ -432,127 +432,237 @@ public final class EmojiStatusSelectionController: ViewController {
},
requestUpdate: { _ in
},
updateSearchQuery: { rawQuery, languageCode in
updateSearchQuery: { query in
guard let strongSelf = self else {
return
}
let query = rawQuery.trimmingCharacters(in: .whitespacesAndNewlines)
if query.isEmpty {
switch query {
case .none:
strongSelf.emojiSearchDisposable.set(nil)
strongSelf.emojiSearchResult.set(.single(nil))
} else {
let context = strongSelf.context
case let .text(rawQuery, languageCode):
let query = rawQuery.trimmingCharacters(in: .whitespacesAndNewlines)
var signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: languageCode, query: query, completeMatch: false)
if !languageCode.lowercased().hasPrefix("en") {
signal = signal
|> mapToSignal { keywords in
return .single(keywords)
|> then(
context.engine.stickers.searchEmojiKeywords(inputLanguageCode: "en-US", query: query, completeMatch: query.count < 3)
|> map { englishKeywords in
return keywords + englishKeywords
}
)
}
}
let hasPremium = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> map { peer -> Bool in
guard case let .user(user) = peer else {
return false
}
return user.isPremium
}
|> distinctUntilChanged
let resultSignal = signal
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
return combineLatest(
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
context.engine.stickers.availableReactions(),
hasPremium
)
|> take(1)
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
for emoticon in keyword.emoticons {
allEmoticons[emoticon] = keyword.keyword
}
if query.isEmpty {
strongSelf.emojiSearchDisposable.set(nil)
strongSelf.emojiSearchResult.set(.single(nil))
} else {
let context = strongSelf.context
var signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: languageCode, query: query, completeMatch: false)
if !languageCode.lowercased().hasPrefix("en") {
signal = signal
|> mapToSignal { keywords in
return .single(keywords)
|> then(
context.engine.stickers.searchEmojiKeywords(inputLanguageCode: "en-US", query: query, completeMatch: query.count < 3)
|> map { englishKeywords in
return keywords + englishKeywords
}
)
}
for entry in view.entries {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
}
default:
break
}
let hasPremium = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> map { peer -> Bool in
guard case let .user(user) = peer else {
return false
}
return user.isPremium
}
|> distinctUntilChanged
let resultSignal = signal
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
return combineLatest(
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
context.engine.stickers.availableReactions(),
hasPremium
)
|> take(1)
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
for emoticon in keyword.emoticons {
allEmoticons[emoticon] = keyword.keyword
}
}
}
var items: [EmojiPagerContentComponent.Item] = []
var existingIds = Set<MediaId>()
for item in result {
if let itemFile = item.1 {
if existingIds.contains(itemFile.fileId) {
for entry in view.entries {
guard let item = entry.item as? StickerPackItem else {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
}
default:
break
}
}
}
var items: [EmojiPagerContentComponent.Item] = []
var existingIds = Set<MediaId>()
for item in result {
if let itemFile = item.1 {
if existingIds.contains(itemFile.fileId) {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
}
}
return [EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
items: items
)]
}
return [EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
items: items
)]
}
strongSelf.emojiSearchDisposable.set((resultSignal
|> delay(0.15, queue: .mainQueue())
|> deliverOnMainQueue).start(next: { result in
guard let strongSelf = self else {
return
}
strongSelf.emojiSearchResult.set(.single((result, AnyHashable(query))))
}))
}
case let .category(query):
if query.isEmpty {
strongSelf.emojiSearchDisposable.set(nil)
strongSelf.emojiSearchResult.set(.single(nil))
} else {
let context = strongSelf.context
let signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: "en", query: query, completeMatch: false)
strongSelf.emojiSearchDisposable.set((resultSignal
|> delay(0.15, queue: .mainQueue())
|> deliverOnMainQueue).start(next: { result in
guard let strongSelf = self else {
return
let hasPremium = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> map { peer -> Bool in
guard case let .user(user) = peer else {
return false
}
return user.isPremium
}
strongSelf.emojiSearchResult.set(.single((result, AnyHashable(query))))
}))
|> distinctUntilChanged
let resultSignal = signal
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
return combineLatest(
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
context.engine.stickers.availableReactions(),
hasPremium
)
|> take(1)
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
var result: [(String, TelegramMediaFile?, String)] = []
var allEmoticons: [String: String] = [:]
for keyword in keywords {
for emoticon in keyword.emoticons {
allEmoticons[emoticon] = keyword.keyword
}
}
for entry in view.entries {
guard let item = entry.item as? StickerPackItem else {
continue
}
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
result.append((alt, item.file, alt))
}
}
default:
break
}
}
}
var items: [EmojiPagerContentComponent.Item] = []
var existingIds = Set<MediaId>()
for item in result {
if let itemFile = item.1 {
if existingIds.contains(itemFile.fileId) {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
}
}
return [EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
items: items
)]
}
}
strongSelf.emojiSearchDisposable.set((resultSignal
|> delay(0.15, queue: .mainQueue())
|> deliverOnMainQueue).start(next: { result in
guard let strongSelf = self else {
return
}
strongSelf.emojiSearchResult.set(.single((result, AnyHashable(query))))
}))
}
}
},
updateScrollingToItemGroup: {