mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
9903cf8243
@ -9115,3 +9115,5 @@ Sorry for the inconvenience.";
|
||||
"Premium.MaxSharedFolderLinksText" = "You can only create **%1$@** invite links. Upgrade to **Telegram Premium** to increase the links limit to **%2$@**.";
|
||||
"Premium.MaxSharedFolderLinksNoPremiumText" = "You can only create **%1$@** invite links. We are working to let you increase this limit in the future.";
|
||||
"Premium.MaxSharedFolderLinksFinalText" = "Sorry, you can only create **%1$@** invite links";
|
||||
|
||||
"Premium.GiftedTitle.Someone" = "Someone";
|
||||
|
@ -2701,15 +2701,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
private func shareFolder(filterId: Int32, data: ChatListFilterData, title: String) {
|
||||
openCreateChatListFolderLink(context: self.context, folderId: filterId, title: title, peerIds: data.includePeers.peers, pushController: { [weak self] c in
|
||||
openCreateChatListFolderLink(context: self.context, folderId: filterId, checkIfExists: true, title: title, peerIds: data.includePeers.peers, pushController: { [weak self] c in
|
||||
self?.push(c)
|
||||
}, presentController: { [weak self] c in
|
||||
self?.present(c, in: .window(.root))
|
||||
}, linkUpdated: { _ in
|
||||
})
|
||||
|
||||
/*self.push(folderInviteLinkListController(context: self.context, filterId: filterId, title: title, allPeerIds: data.includePeers.peers, currentInvitation: nil, linkUpdated: { _ in
|
||||
}))*/
|
||||
}
|
||||
|
||||
private func askForFilterRemoval(id: Int32) {
|
||||
|
@ -1297,7 +1297,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
return
|
||||
}
|
||||
|
||||
openCreateChatListFolderLink(context: context, folderId: currentPreset.id, title: currentPreset.title, peerIds: state.additionallyIncludePeers, pushController: { c in
|
||||
openCreateChatListFolderLink(context: context, folderId: currentPreset.id, checkIfExists: false, title: currentPreset.title, peerIds: state.additionallyIncludePeers, pushController: { c in
|
||||
pushControllerImpl?(c)
|
||||
}, presentController: { c in
|
||||
presentControllerImpl?(c, nil)
|
||||
@ -1504,42 +1504,91 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
return controller
|
||||
}
|
||||
|
||||
func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, title: String, peerIds: [EnginePeer.Id], pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController) -> Void, linkUpdated: @escaping (ExportedChatFolderLink?) -> Void) {
|
||||
func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, checkIfExists: Bool, title: String, peerIds: [EnginePeer.Id], pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController) -> Void, linkUpdated: @escaping (ExportedChatFolderLink?) -> Void) {
|
||||
if peerIds.isEmpty {
|
||||
return
|
||||
}
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataList(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peers in
|
||||
let peers = peers.compactMap({ $0 })
|
||||
if peers.allSatisfy({ !canShareLinkToPeer(peer: $0) }) {
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: nil, linkUpdated: linkUpdated))
|
||||
} else {
|
||||
let _ = (context.engine.peers.exportChatFolder(filterId: folderId, title: "", peerIds: peerIds)
|
||||
|> deliverOnMainQueue).start(next: { link in
|
||||
linkUpdated(link)
|
||||
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: link.peerIds, currentInvitation: link, linkUpdated: linkUpdated))
|
||||
}, error: { error in
|
||||
//TODO:localize
|
||||
let text: String
|
||||
switch error {
|
||||
case .generic:
|
||||
text = "An error occurred"
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
if limit < premiumLimit {
|
||||
let limitController = context.sharedContext.makePremiumLimitController(context: context, subject: .linksPerSharedFolder, count: limit, action: {
|
||||
})
|
||||
pushController(limitController)
|
||||
|
||||
return
|
||||
}
|
||||
text = "You can't create more links."
|
||||
|
||||
let existingLink: Signal<ExportedChatFolderLink?, NoError>
|
||||
if checkIfExists {
|
||||
existingLink = combineLatest(
|
||||
context.engine.peers.getExportedChatFolderLinks(id: folderId),
|
||||
context.engine.data.get(
|
||||
EngineDataList(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
)
|
||||
|> map { result, peers -> ExportedChatFolderLink? in
|
||||
var enabledPeerIds: [EnginePeer.Id] = []
|
||||
for peer in peers {
|
||||
if let peer, canShareLinkToPeer(peer: peer) {
|
||||
enabledPeerIds.append(peer.id)
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentController(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
})
|
||||
}
|
||||
|
||||
guard let result else {
|
||||
return nil
|
||||
}
|
||||
|
||||
for link in result {
|
||||
if Set(link.peerIds) == Set(enabledPeerIds) {
|
||||
return link
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
existingLink = .single(nil)
|
||||
}
|
||||
|
||||
let _ = (existingLink
|
||||
|> deliverOnMainQueue).start(next: { existingLink in
|
||||
if let existingLink {
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: existingLink, linkUpdated: linkUpdated))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataList(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peers in
|
||||
let peers = peers.compactMap({ $0 })
|
||||
if peers.allSatisfy({ !canShareLinkToPeer(peer: $0) }) {
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: nil, linkUpdated: linkUpdated))
|
||||
} else {
|
||||
var enabledPeerIds: [EnginePeer.Id] = []
|
||||
for peer in peers {
|
||||
if canShareLinkToPeer(peer: peer) {
|
||||
enabledPeerIds.append(peer.id)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = (context.engine.peers.exportChatFolder(filterId: folderId, title: "", peerIds: enabledPeerIds)
|
||||
|> deliverOnMainQueue).start(next: { link in
|
||||
linkUpdated(link)
|
||||
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: link, linkUpdated: linkUpdated))
|
||||
}, error: { error in
|
||||
//TODO:localize
|
||||
let text: String
|
||||
switch error {
|
||||
case .generic:
|
||||
text = "An error occurred"
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
if limit < premiumLimit {
|
||||
let limitController = context.sharedContext.makePremiumLimitController(context: context, subject: .linksPerSharedFolder, count: limit, action: {
|
||||
})
|
||||
pushController(limitController)
|
||||
|
||||
return
|
||||
}
|
||||
text = "You can't create more links."
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentController(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
||||
let host: String? = concealed ? urlString : parsedUrl?.host
|
||||
if let url = parsedUrl, let host = host {
|
||||
primaryUrl = urlString
|
||||
title = NSAttributedString(string: tempTitleString as String, font: titleFont, textColor: item.presentationData.theme.theme.list.itemPrimaryTextColor)
|
||||
title = NSAttributedString(string: (tempTitleString as String).capitalized, font: titleFont, textColor: item.presentationData.theme.theme.list.itemPrimaryTextColor)
|
||||
if url.path.hasPrefix("/addstickers/") {
|
||||
iconText = NSAttributedString(string: "S", font: iconFont, textColor: UIColor.white)
|
||||
} else if url.path.hasPrefix("/addemoji/") {
|
||||
|
@ -2039,23 +2039,22 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
availableProducts = .single([])
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let otherPeerName: Signal<String?, NoError>
|
||||
if case let .gift(fromPeerId, toPeerId, _) = source {
|
||||
let otherPeerId = fromPeerId != context.account.peerId ? fromPeerId : toPeerId
|
||||
otherPeerName = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: otherPeerId))
|
||||
|> map { peer -> String? in
|
||||
return peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
return peer?.compactDisplayTitle
|
||||
}
|
||||
} else if case let .profile(peerId) = source {
|
||||
otherPeerName = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> map { peer -> String? in
|
||||
return peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
return peer?.compactDisplayTitle
|
||||
}
|
||||
} else if case let .emojiStatus(peerId, _, _, _) = source {
|
||||
otherPeerName = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> map { peer -> String? in
|
||||
return peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
return peer?.compactDisplayTitle
|
||||
}
|
||||
} else {
|
||||
otherPeerName = .single(nil)
|
||||
@ -2360,26 +2359,12 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let textColor = environment.theme.list.itemPrimaryTextColor
|
||||
let accentColor: UIColor
|
||||
if case .emojiStatus = context.component.source {
|
||||
accentColor = environment.theme.list.itemAccentColor
|
||||
} else {
|
||||
accentColor = UIColor(rgb: 0x597cf5)
|
||||
}
|
||||
|
||||
let textFont = Font.bold(18.0)
|
||||
let boldTextFont = Font.bold(18.0)
|
||||
|
||||
let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: accentColor), linkAttribute: { _ in
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
var loadedEmojiPack: LoadedStickerPack?
|
||||
var highlightableLinks = false
|
||||
let secondaryTitleText: String
|
||||
if let otherPeerName = state.otherPeerName {
|
||||
var isAnonymous = false
|
||||
if var otherPeerName = state.otherPeerName {
|
||||
if case let .emojiStatus(_, _, file, maybeEmojiPack) = context.component.source, let emojiPack = maybeEmojiPack, case let .result(info, _, _) = emojiPack {
|
||||
loadedEmojiPack = maybeEmojiPack
|
||||
highlightableLinks = true
|
||||
@ -2411,6 +2396,10 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
secondaryTitleText = ""
|
||||
}
|
||||
} else {
|
||||
if fromPeerId.namespace == Namespaces.Peer.CloudUser && fromPeerId.id._internalGetInt64Value() == 777000 {
|
||||
isAnonymous = true
|
||||
otherPeerName = environment.strings.Premium_GiftedTitle_Someone
|
||||
}
|
||||
if duration == 12 {
|
||||
secondaryTitleText = environment.strings.Premium_GiftedTitle_12Month(otherPeerName).string
|
||||
} else if duration == 6 {
|
||||
@ -2428,6 +2417,20 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
secondaryTitleText = ""
|
||||
}
|
||||
|
||||
let textColor = environment.theme.list.itemPrimaryTextColor
|
||||
let accentColor: UIColor
|
||||
if case .emojiStatus = context.component.source {
|
||||
accentColor = environment.theme.list.itemAccentColor
|
||||
} else {
|
||||
accentColor = UIColor(rgb: 0x597cf5)
|
||||
}
|
||||
|
||||
let textFont = Font.bold(18.0)
|
||||
let boldTextFont = Font.bold(18.0)
|
||||
let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: isAnonymous ? textColor : accentColor), linkAttribute: { _ in
|
||||
return nil
|
||||
})
|
||||
|
||||
let secondaryAttributedText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(secondaryTitleText, attributes: markdownAttributes))
|
||||
if let emojiFile = state.emojiFile {
|
||||
let range = (secondaryAttributedText.string as NSString).range(of: "#")
|
||||
|
@ -114,7 +114,7 @@ public class StickerShimmerEffectNode: ASDisplayNode {
|
||||
self.currentSize = size
|
||||
|
||||
self.backgroundNode.backgroundColor = foregroundColor
|
||||
self.backgroundNode.isHidden = true//!enableEffect
|
||||
//self.backgroundNode.isHidden = true//!enableEffect
|
||||
|
||||
if enableEffect {
|
||||
self.effectNode.update(backgroundColor: backgroundColor == nil ? .clear : foregroundColor, foregroundColor: shimmeringColor, horizontal: true, effectSize: nil, globalTimeOffset: true, duration: nil)
|
||||
|
@ -108,7 +108,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
|
||||
if let textEntities = textEntities, !textEntities.isEmpty && !tags.contains(.webPage) {
|
||||
for entity in textEntities {
|
||||
switch entity.type {
|
||||
case .Url, .Email:
|
||||
case .Url, .TextUrl, .Email:
|
||||
if media.isEmpty || !(media.first is TelegramMediaWebpage) {
|
||||
tags.insert(.webPage)
|
||||
}
|
||||
|
@ -394,79 +394,47 @@ func _internal_searchEmoji(account: Account, query: [String], scope: SearchStick
|
||||
if query == ["\u{2764}"] {
|
||||
query = ["\u{2764}\u{FE0F}"]
|
||||
}
|
||||
|
||||
let combinedQuery = query.sorted().joined(separator: "")
|
||||
let querySet = Set(query)
|
||||
return account.postbox.transaction { transaction -> ([FoundStickerItem], CachedStickerQueryResult?, Bool, SearchStickersConfiguration) in
|
||||
let isPremium = transaction.getPeer(account.peerId)?.isPremium ?? false
|
||||
|
||||
var result: [FoundStickerItem] = []
|
||||
if scope.contains(.installed) {
|
||||
var currentItems = Set<MediaId>(result.map { $0.file.fileId })
|
||||
var recentItems: [TelegramMediaFile] = []
|
||||
var recentAnimatedItems: [TelegramMediaFile] = []
|
||||
var recentItemsIds = Set<MediaId>()
|
||||
var matchingRecentItemsIds = Set<MediaId>()
|
||||
|
||||
for entry in transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.LocalRecentEmoji) {
|
||||
if let item = entry.contents.get(RecentEmojiItem.self), case let .file(file) = item.content {
|
||||
if !currentItems.contains(file.fileId) {
|
||||
currentItems.insert(file.fileId)
|
||||
|
||||
for case let .Sticker(displayText, _, _) in file.attributes {
|
||||
for queryItem in query {
|
||||
if displayText.hasPrefix(queryItem) {
|
||||
matchingRecentItemsIds.insert(file.fileId)
|
||||
break
|
||||
}
|
||||
}
|
||||
recentItemsIds.insert(file.fileId)
|
||||
if file.isAnimatedSticker || file.isVideoSticker {
|
||||
recentAnimatedItems.append(file)
|
||||
} else {
|
||||
recentItems.append(file)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var searchQueries: [ItemCollectionSearchQuery] = query.map { queryItem -> ItemCollectionSearchQuery in
|
||||
return .exact(ValueBoxKey(queryItem))
|
||||
}
|
||||
if query == ["\u{2764}"] {
|
||||
searchQueries = [.any([ValueBoxKey("\u{2764}"), ValueBoxKey("\u{2764}\u{FE0F}")])]
|
||||
}
|
||||
|
||||
var currentItems = Set<MediaId>()
|
||||
var installedItems: [FoundStickerItem] = []
|
||||
|
||||
for searchQuery in searchQueries {
|
||||
for item in transaction.searchItemCollection(namespace: Namespaces.ItemCollection.CloudEmojiPacks, query: searchQuery) {
|
||||
if let item = item as? StickerPackItem {
|
||||
if !currentItems.contains(item.file.fileId) {
|
||||
currentItems.insert(item.file.fileId)
|
||||
|
||||
var stringRepresentations: [String] = []
|
||||
for key in item.indexKeys {
|
||||
key.withDataNoCopy { data in
|
||||
if let string = String(data: data, encoding: .utf8) {
|
||||
stringRepresentations.append(string)
|
||||
for info in transaction.getItemCollectionsInfos(namespace: Namespaces.ItemCollection.CloudEmojiPacks) {
|
||||
if let info = info.1 as? StickerPackCollectionInfo {
|
||||
let items = transaction.getItemCollectionItems(collectionId: info.id)
|
||||
for item in items {
|
||||
if let item = item as? StickerPackItem {
|
||||
let file = item.file
|
||||
if !currentItems.contains(file.fileId) {
|
||||
currentItems.insert(file.fileId)
|
||||
|
||||
var stringRepresentations: [String] = []
|
||||
for key in item.indexKeys {
|
||||
key.withDataNoCopy { data in
|
||||
if let string = String(data: data, encoding: .utf8) {
|
||||
stringRepresentations.append(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
for stringRepresentation in stringRepresentations {
|
||||
if querySet.contains(stringRepresentation) {
|
||||
installedItems.append(FoundStickerItem(file: file, stringRepresentations: stringRepresentations))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !recentItemsIds.contains(item.file.fileId) {
|
||||
installedItems.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
|
||||
} else {
|
||||
matchingRecentItemsIds.insert(item.file.fileId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.append(contentsOf: installedItems)
|
||||
}
|
||||
|
||||
let combinedQuery = query.joined(separator: "")
|
||||
|
||||
var cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedEmojiQueryResults, key: CachedStickerQueryResult.cacheKey(combinedQuery)))?.get(CachedStickerQueryResult.self)
|
||||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
@ -476,10 +444,6 @@ func _internal_searchEmoji(account: Account, query: [String], scope: SearchStick
|
||||
if let currentCached = cached, currentTime > currentCached.timestamp + searchStickersConfiguration.cacheTimeout {
|
||||
cached = nil
|
||||
}
|
||||
#if DEBUG
|
||||
cached = nil
|
||||
#endif
|
||||
|
||||
return (result, cached, isPremium, searchStickersConfiguration)
|
||||
}
|
||||
|> mapToSignal { localItems, cached, isPremium, searchStickersConfiguration -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> in
|
||||
@ -487,29 +451,15 @@ func _internal_searchEmoji(account: Account, query: [String], scope: SearchStick
|
||||
return .single((localItems, true))
|
||||
}
|
||||
|
||||
var tempResult: [FoundStickerItem] = []
|
||||
let currentItemIds = Set<MediaId>(localItems.map { $0.file.fileId })
|
||||
|
||||
var otherItems: [FoundStickerItem] = []
|
||||
|
||||
for item in localItems {
|
||||
otherItems.append(item)
|
||||
}
|
||||
|
||||
var intermediateResult: [FoundStickerItem] = localItems
|
||||
var currentItemIds = Set<MediaId>(localItems.map { $0.file.fileId })
|
||||
if let cached = cached {
|
||||
var cachedItems: [FoundStickerItem] = []
|
||||
|
||||
for file in cached.items {
|
||||
if !currentItemIds.contains(file.fileId) {
|
||||
cachedItems.append(FoundStickerItem(file: file, stringRepresentations: []))
|
||||
currentItemIds.insert(file.fileId)
|
||||
intermediateResult.append(FoundStickerItem(file: file, stringRepresentations: []))
|
||||
}
|
||||
}
|
||||
|
||||
otherItems.append(contentsOf: cachedItems)
|
||||
|
||||
let allOtherItems = otherItems
|
||||
|
||||
tempResult.append(contentsOf: allOtherItems)
|
||||
}
|
||||
|
||||
let remote = account.network.request(Api.functions.messages.searchCustomEmoji(emoticon: query.joined(separator: ""), hash: cached?.hash ?? 0))
|
||||
@ -536,39 +486,29 @@ func _internal_searchEmoji(account: Account, query: [String], scope: SearchStick
|
||||
|> mapToSignal { result -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> in
|
||||
return account.postbox.transaction { transaction -> (items: [FoundStickerItem], isFinalResult: Bool) in
|
||||
if let (fileItems, hash) = result {
|
||||
var result: [FoundStickerItem] = []
|
||||
var result: [FoundStickerItem] = localItems
|
||||
var currentItemIds = Set<MediaId>(localItems.map { $0.file.fileId })
|
||||
|
||||
var otherItems: [FoundStickerItem] = []
|
||||
|
||||
for item in localItems {
|
||||
otherItems.append(item)
|
||||
}
|
||||
|
||||
|
||||
var files: [TelegramMediaFile] = []
|
||||
for file in fileItems {
|
||||
files.append(file)
|
||||
if !currentItemIds.contains(file.fileId) {
|
||||
currentItemIds.insert(file.fileId)
|
||||
otherItems.append(FoundStickerItem(file: file, stringRepresentations: []))
|
||||
result.append(FoundStickerItem(file: file, stringRepresentations: []))
|
||||
}
|
||||
}
|
||||
|
||||
let allOtherItems = otherItems
|
||||
|
||||
result.append(contentsOf: allOtherItems)
|
||||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if let entry = CodableEntry(CachedStickerQueryResult(items: files, hash: hash, timestamp: currentTime)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedEmojiQueryResults, key: CachedStickerQueryResult.cacheKey(query.joined(separator: ""))), entry: entry)
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedEmojiQueryResults, key: CachedStickerQueryResult.cacheKey(combinedQuery)), entry: entry)
|
||||
}
|
||||
|
||||
return (result, true)
|
||||
}
|
||||
return (tempResult, true)
|
||||
return (intermediateResult, true)
|
||||
}
|
||||
}
|
||||
return .single((tempResult, false))
|
||||
return .single((intermediateResult, false))
|
||||
|> then(remote)
|
||||
}
|
||||
}
|
||||
|
@ -1031,64 +1031,44 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
let resultSignal = signal
|
||||
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
||||
var allEmoticons: [String: String] = [:]
|
||||
for keyword in keywords {
|
||||
for emoticon in keyword.emoticons {
|
||||
allEmoticons[emoticon] = keyword.keyword
|
||||
}
|
||||
}
|
||||
|
||||
return combineLatest(
|
||||
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
|
||||
context.engine.stickers.availableReactions(),
|
||||
hasPremium
|
||||
hasPremium,
|
||||
context.engine.stickers.searchEmoji(emojiString: Array(allEmoticons.keys))
|
||||
)
|
||||
|> 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
|
||||
}
|
||||
|> mapToSignal { hasPremium, foundEmoji -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
||||
if foundEmoji.items.isEmpty && !foundEmoji.isFinalResult {
|
||||
return .complete()
|
||||
}
|
||||
|
||||
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)
|
||||
for itemFile in foundEmoji.items {
|
||||
if existingIds.contains(itemFile.fileId) {
|
||||
continue
|
||||
}
|
||||
existingIds.insert(itemFile.fileId)
|
||||
if itemFile.isPremiumEmoji && !hasPremium {
|
||||
continue
|
||||
}
|
||||
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(
|
||||
|
||||
return .single([EmojiPagerContentComponent.ItemGroup(
|
||||
supergroupId: "search",
|
||||
groupId: "search",
|
||||
title: nil,
|
||||
@ -1103,7 +1083,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
headerItem: nil,
|
||||
fillWithLoadingPlaceholders: false,
|
||||
items: items
|
||||
)]
|
||||
)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,7 +1151,6 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
return
|
||||
}
|
||||
if group.items.isEmpty && !result.isFinalResult {
|
||||
//self.emojiSearchStateValue.isSearching = true
|
||||
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: [
|
||||
EmojiPagerContentComponent.ItemGroup(
|
||||
supergroupId: "search",
|
||||
@ -1192,10 +1171,8 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
], id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
|
||||
return
|
||||
}
|
||||
//DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0, execute: {
|
||||
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: result.items, id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
|
||||
version += 1
|
||||
//})
|
||||
self.emojiSearchStateValue = EmojiSearchState(result: EmojiSearchResult(groups: result.items, id: AnyHashable(value), version: version, isPreset: true), isSearching: false)
|
||||
version += 1
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
@ -1366,33 +1366,5 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
func shouldDisplayInlineDateReactions(message: Message, isPremium: Bool, forceInline: Bool) -> Bool {
|
||||
if forceInline {
|
||||
return true
|
||||
}
|
||||
|
||||
if message.id.peerId.namespace == Namespaces.Peer.CloudUser || message.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
if let chatPeer = message.peers[message.id.peerId] as? TelegramUser, chatPeer.isPremium {
|
||||
return false
|
||||
}
|
||||
if let author = message.author as? TelegramUser, author.isPremium {
|
||||
return false
|
||||
}
|
||||
if isPremium {
|
||||
return false
|
||||
}
|
||||
|
||||
if let effectiveReactions = message.effectiveReactions {
|
||||
if effectiveReactions.count > 1 {
|
||||
return false
|
||||
}
|
||||
for reaction in effectiveReactions {
|
||||
if case .custom = reaction.value {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return forceInline
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user