mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Emoji status and reaction improvements
This commit is contained in:
@@ -19,6 +19,42 @@ import TextFormat
|
||||
import AppBundle
|
||||
import GZip
|
||||
|
||||
private func randomGenericReactionEffect(context: AccountContext) -> Signal<String?, NoError> {
|
||||
return context.engine.stickers.loadedStickerPack(reference: .emojiGenericAnimations, forceActualized: false)
|
||||
|> map { result -> [TelegramMediaFile]? in
|
||||
switch result {
|
||||
case let .result(_, items, _):
|
||||
return items.map(\.file)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> filter { $0 != nil }
|
||||
|> take(1)
|
||||
|> mapToSignal { items -> Signal<String?, NoError> in
|
||||
guard let items = items else {
|
||||
return .single(nil)
|
||||
}
|
||||
guard let file = items.randomElement() else {
|
||||
return .single(nil)
|
||||
}
|
||||
return Signal { subscriber in
|
||||
let fetchDisposable = freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: file)).start()
|
||||
let dataDisposable = (context.account.postbox.mediaBox.resourceData(file.resource)
|
||||
|> filter(\.complete)
|
||||
|> take(1)).start(next: { data in
|
||||
subscriber.putNext(data.path)
|
||||
subscriber.putCompletion()
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
fetchDisposable.dispose()
|
||||
dataDisposable.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class EmojiStatusSelectionComponent: Component {
|
||||
public typealias EnvironmentType = Empty
|
||||
|
||||
@@ -192,6 +228,9 @@ public final class EmojiStatusSelectionController: ViewController {
|
||||
private var availableReactions: AvailableReactions?
|
||||
private var availableReactionsDisposable: Disposable?
|
||||
|
||||
private var genericReactionEffectDisposable: Disposable?
|
||||
private var genericReactionEffect: String?
|
||||
|
||||
private var hapticFeedback: HapticFeedback?
|
||||
|
||||
private var isDismissed: Bool = false
|
||||
@@ -310,11 +349,17 @@ public final class EmojiStatusSelectionController: ViewController {
|
||||
}
|
||||
strongSelf.availableReactions = availableReactions
|
||||
})
|
||||
|
||||
self.genericReactionEffectDisposable = (randomGenericReactionEffect(context: context)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] path in
|
||||
self?.genericReactionEffect = path
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.emojiContentDisposable?.dispose()
|
||||
self.availableReactionsDisposable?.dispose()
|
||||
self.genericReactionEffectDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func refreshLayout(transition: Transition) {
|
||||
@@ -373,42 +418,56 @@ public final class EmojiStatusSelectionController: ViewController {
|
||||
view.isOpaque = false
|
||||
|
||||
effectView = view
|
||||
} else if let itemFile = item.itemFile, let url = getAppBundle().url(forResource: "generic_reaction_small_effect", withExtension: "json"), let composition = Animation.filepath(url.path) {
|
||||
let view = AnimationView(animation: composition, configuration: LottieConfiguration(renderingEngine: .mainThread, decodingStrategy: .codable))
|
||||
view.animationSpeed = 1.0
|
||||
view.backgroundColor = nil
|
||||
view.isOpaque = false
|
||||
|
||||
let animationCache = self.context.animationCache
|
||||
let animationRenderer = self.context.animationRenderer
|
||||
|
||||
for i in 1 ... 7 {
|
||||
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
|
||||
for animationLayer in allLayers {
|
||||
let baseItemLayer = InlineStickerItemLayer(
|
||||
context: self.context,
|
||||
attemptSynchronousLoad: false,
|
||||
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: itemFile.fileId.id, file: itemFile),
|
||||
file: item.itemFile,
|
||||
cache: animationCache,
|
||||
renderer: animationRenderer,
|
||||
placeholderColor: UIColor(white: 0.0, alpha: 0.0),
|
||||
pointSize: CGSize(width: 32.0, height: 32.0)
|
||||
)
|
||||
|
||||
if let sublayers = animationLayer.sublayers {
|
||||
for sublayer in sublayers {
|
||||
sublayer.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
baseItemLayer.isVisibleForAnimations = true
|
||||
baseItemLayer.frame = CGRect(origin: CGPoint(x: -0.0, y: -0.0), size: CGSize(width: 500.0, height: 500.0))
|
||||
animationLayer.addSublayer(baseItemLayer)
|
||||
} else if let itemFile = item.itemFile {
|
||||
var effectData: Data?
|
||||
if let genericReactionEffect = self.genericReactionEffect, let data = try? Data(contentsOf: URL(fileURLWithPath: genericReactionEffect)) {
|
||||
effectData = TGGUnzipData(data, 5 * 1024 * 1024) ?? data
|
||||
} else {
|
||||
if let url = getAppBundle().url(forResource: "generic_reaction_small_effect", withExtension: "json") {
|
||||
effectData = try? Data(contentsOf: url)
|
||||
}
|
||||
}
|
||||
|
||||
effectView = view
|
||||
if let effectData = effectData, let composition = try? Animation.from(data: effectData) {
|
||||
let view = AnimationView(animation: composition, configuration: LottieConfiguration(renderingEngine: .mainThread, decodingStrategy: .codable))
|
||||
view.animationSpeed = 1.0
|
||||
view.backgroundColor = nil
|
||||
view.isOpaque = false
|
||||
|
||||
let animationCache = self.context.animationCache
|
||||
let animationRenderer = self.context.animationRenderer
|
||||
|
||||
for i in 1 ... 7 {
|
||||
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
|
||||
for animationLayer in allLayers {
|
||||
let baseItemLayer = InlineStickerItemLayer(
|
||||
context: self.context,
|
||||
attemptSynchronousLoad: false,
|
||||
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: itemFile.fileId.id, file: itemFile),
|
||||
file: item.itemFile,
|
||||
cache: animationCache,
|
||||
renderer: animationRenderer,
|
||||
placeholderColor: UIColor(white: 0.0, alpha: 0.0),
|
||||
pointSize: CGSize(width: 32.0, height: 32.0)
|
||||
)
|
||||
if item.accentTint {
|
||||
baseItemLayer.contentTintColor = self.presentationData.theme.list.itemAccentColor
|
||||
}
|
||||
|
||||
if let sublayers = animationLayer.sublayers {
|
||||
for sublayer in sublayers {
|
||||
sublayer.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
baseItemLayer.isVisibleForAnimations = true
|
||||
baseItemLayer.frame = CGRect(origin: CGPoint(x: -0.0, y: -0.0), size: CGSize(width: 500.0, height: 500.0))
|
||||
animationLayer.addSublayer(baseItemLayer)
|
||||
}
|
||||
}
|
||||
|
||||
effectView = view
|
||||
}
|
||||
}
|
||||
|
||||
if let sourceCopyLayer = sourceLayer.snapshotContentTree() {
|
||||
|
||||
Reference in New Issue
Block a user