Emoji status and reaction improvements

This commit is contained in:
Ali
2022-08-30 18:38:47 +04:00
parent 5ca7417ee1
commit b924ea326e
48 changed files with 1386 additions and 413 deletions

View File

@@ -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() {