mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 17:30:12 +00:00
Emoji improvements
This commit is contained in:
parent
561b1ddc08
commit
489c410aca
@ -1173,6 +1173,7 @@ public class Account {
|
|||||||
}
|
}
|
||||||
self.managedOperationsDisposable.add(managedGreetingStickers(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedGreetingStickers(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedPremiumStickers(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedPremiumStickers(postbox: self.postbox, network: self.network).start())
|
||||||
|
self.managedOperationsDisposable.add(managedAllPremiumStickers(postbox: self.postbox, network: self.network).start())
|
||||||
|
|
||||||
if !supplementary {
|
if !supplementary {
|
||||||
let mediaBox = postbox.mediaBox
|
let mediaBox = postbox.mediaBox
|
||||||
|
|||||||
@ -178,3 +178,27 @@ func managedPremiumStickers(postbox: Postbox, network: Network) -> Signal<Void,
|
|||||||
})
|
})
|
||||||
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func managedAllPremiumStickers(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudAllPremiumStickers, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
||||||
|
return network.request(Api.functions.messages.getStickers(emoticon: "📂⭐️", hash: 0))
|
||||||
|
|> retryRequest
|
||||||
|
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
|
||||||
|
switch result {
|
||||||
|
case .stickersNotModified:
|
||||||
|
return .single(nil)
|
||||||
|
case let .stickers(_, stickers):
|
||||||
|
var items: [OrderedItemListEntry] = []
|
||||||
|
for sticker in stickers {
|
||||||
|
if let file = telegramMediaFileFromApiDocument(sticker), let id = file.id {
|
||||||
|
if let entry = CodableEntry(RecentMediaItem(file)) {
|
||||||
|
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: entry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .single(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||||
|
}
|
||||||
|
|||||||
@ -67,6 +67,7 @@ public struct Namespaces {
|
|||||||
public static let CloudPremiumStickers: Int32 = 13
|
public static let CloudPremiumStickers: Int32 = 13
|
||||||
public static let LocalRecentEmoji: Int32 = 14
|
public static let LocalRecentEmoji: Int32 = 14
|
||||||
public static let CloudFeaturedEmojiPacks: Int32 = 15
|
public static let CloudFeaturedEmojiPacks: Int32 = 15
|
||||||
|
public static let CloudAllPremiumStickers: Int32 = 16
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct CachedItemCollection {
|
public struct CachedItemCollection {
|
||||||
|
|||||||
@ -218,7 +218,8 @@ private final class ItemAnimationContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static let queue = Queue(name: "ItemAnimationContext", qos: .default)
|
static let queue0 = Queue(name: "ItemAnimationContext-0", qos: .default)
|
||||||
|
static let queue1 = Queue(name: "ItemAnimationContext-1", qos: .default)
|
||||||
|
|
||||||
private let cache: AnimationCache
|
private let cache: AnimationCache
|
||||||
private let stateUpdated: () -> Void
|
private let stateUpdated: () -> Void
|
||||||
@ -667,7 +668,49 @@ public final class MultiAnimationRendererImpl: MultiAnimationRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !tasks.isEmpty {
|
if !tasks.isEmpty {
|
||||||
ItemAnimationContext.queue.async {
|
if tasks.count > 2 {
|
||||||
|
let tasks0 = Array(tasks.prefix(tasks.count / 2))
|
||||||
|
let tasks1 = Array(tasks.suffix(tasks.count - tasks0.count))
|
||||||
|
|
||||||
|
var tasks0Completions: [() -> Void]?
|
||||||
|
var tasks1Completions: [() -> Void]?
|
||||||
|
|
||||||
|
let complete: (Int, [() -> Void]) -> Void = { index, completions in
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
if index == 0 {
|
||||||
|
tasks0Completions = completions
|
||||||
|
} else if index == 1 {
|
||||||
|
tasks1Completions = completions
|
||||||
|
}
|
||||||
|
if let tasks0Completions = tasks0Completions, let tasks1Completions = tasks1Completions {
|
||||||
|
for completion in tasks0Completions {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
for completion in tasks1Completions {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemAnimationContext.queue0.async {
|
||||||
|
var completions: [() -> Void] = []
|
||||||
|
for task in tasks0 {
|
||||||
|
let complete = task.task()
|
||||||
|
completions.append(complete)
|
||||||
|
}
|
||||||
|
complete(0, completions)
|
||||||
|
}
|
||||||
|
ItemAnimationContext.queue1.async {
|
||||||
|
var completions: [() -> Void] = []
|
||||||
|
for task in tasks1 {
|
||||||
|
let complete = task.task()
|
||||||
|
completions.append(complete)
|
||||||
|
}
|
||||||
|
complete(1, completions)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ItemAnimationContext.queue0.async {
|
||||||
var completions: [() -> Void] = []
|
var completions: [() -> Void] = []
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
let complete = task.task()
|
let complete = task.task()
|
||||||
@ -685,3 +728,4 @@ public final class MultiAnimationRendererImpl: MultiAnimationRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -362,7 +362,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
let emojiItems = emojiInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, isStandalone: false, areCustomEmojiEnabled: areCustomEmojiEnabled, chatPeerId: chatPeerId)
|
let emojiItems = emojiInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, isStandalone: false, areCustomEmojiEnabled: areCustomEmojiEnabled, chatPeerId: chatPeerId)
|
||||||
|
|
||||||
let stickerNamespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks]
|
let stickerNamespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks]
|
||||||
let stickerOrderedItemListCollectionIds: [Int32] = [Namespaces.OrderedItemList.CloudSavedStickers, Namespaces.OrderedItemList.CloudRecentStickers, Namespaces.OrderedItemList.CloudPremiumStickers]
|
let stickerOrderedItemListCollectionIds: [Int32] = [Namespaces.OrderedItemList.CloudSavedStickers, Namespaces.OrderedItemList.CloudRecentStickers, Namespaces.OrderedItemList.CloudAllPremiumStickers]
|
||||||
|
|
||||||
struct PeerSpecificPackData: Equatable {
|
struct PeerSpecificPackData: Equatable {
|
||||||
var info: StickerPackCollectionInfo
|
var info: StickerPackCollectionInfo
|
||||||
@ -440,7 +440,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
recentStickers = orderedView
|
recentStickers = orderedView
|
||||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudSavedStickers {
|
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudSavedStickers {
|
||||||
savedStickers = orderedView
|
savedStickers = orderedView
|
||||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudPremiumStickers {
|
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudAllPremiumStickers {
|
||||||
cloudPremiumStickers = orderedView
|
cloudPremiumStickers = orderedView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2608,8 +2608,26 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
let replacementText = NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: emojiAttribute])
|
let replacementText = NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: emojiAttribute])
|
||||||
|
|
||||||
let range = currentEmojiSuggestion.position.range
|
let range = currentEmojiSuggestion.position.range
|
||||||
|
let previousText = inputText.attributedSubstring(from: range)
|
||||||
inputText.replaceCharacters(in: range, with: replacementText)
|
inputText.replaceCharacters(in: range, with: replacementText)
|
||||||
|
|
||||||
|
var replacedUpperBound = range.lowerBound
|
||||||
|
while true {
|
||||||
|
if inputText.attributedSubstring(from: NSRange(location: 0, length: replacedUpperBound)).string.hasSuffix(previousText.string) {
|
||||||
|
let replaceRange = NSRange(location: replacedUpperBound - previousText.length, length: previousText.length)
|
||||||
|
if replaceRange.location < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inputText.attributedSubstring(from: replaceRange).string != previousText.string {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
inputText.replaceCharacters(in: replaceRange, with: NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: emojiAttribute.stickerPack, fileId: emojiAttribute.fileId, file: emojiAttribute.file)]))
|
||||||
|
replacedUpperBound = replaceRange.lowerBound
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let selectionPosition = range.lowerBound + (replacementText.string as NSString).length
|
let selectionPosition = range.lowerBound + (replacementText.string as NSString).length
|
||||||
|
|
||||||
return (ChatTextInputState(inputText: inputText, selectionRange: selectionPosition ..< selectionPosition), inputMode)
|
return (ChatTextInputState(inputText: inputText, selectionRange: selectionPosition ..< selectionPosition), inputMode)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user