mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-06-20 18:24:43 +00:00
Various improvements
This commit is contained in:
@@ -878,6 +878,8 @@ public class PremiumDemoScreen: ViewControllerComponentContainer {
|
||||
public init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source = .other, action: @escaping () -> Void) {
|
||||
super.init(context: context, component: DemoSheetComponent(context: context, subject: subject, source: source, action: action), navigationBarAppearance: .none)
|
||||
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
|
||||
self.navigationPresentation = .flatModal
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import AsyncDisplayKit
|
||||
import ComponentFlow
|
||||
import TelegramCore
|
||||
@@ -66,7 +67,9 @@ final class ReactionsCarouselComponent: Component {
|
||||
}
|
||||
|
||||
if isDisplaying && !self.isVisible {
|
||||
self.node?.animateIn()
|
||||
self.node?.setVisible(true)
|
||||
} else if !isDisplaying && self.isVisible {
|
||||
self.node?.setVisible(false)
|
||||
}
|
||||
self.isVisible = isDisplaying
|
||||
|
||||
@@ -85,6 +88,9 @@ final class ReactionsCarouselComponent: Component {
|
||||
|
||||
private let itemSize = CGSize(width: 110.0, height: 110.0)
|
||||
|
||||
//private let order = ["👌","😍","🤡","🕊","🥱","🥴"]
|
||||
private let order = ["😍","👌","🥴","🥱","🕊","🤡"]
|
||||
|
||||
private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
private let context: AccountContext
|
||||
private let theme: PresentationTheme
|
||||
@@ -105,10 +111,27 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
private let positionDelta: Double
|
||||
|
||||
private var previousInteractionTimestamp: Double = 0.0
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
private var hasIdleAnimations = false
|
||||
|
||||
init(context: AccountContext, theme: PresentationTheme, reactions: [AvailableReactions.Reaction]) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.reactions = Array(reactions.shuffled().prefix(6))
|
||||
|
||||
var reactionMap: [String: AvailableReactions.Reaction] = [:]
|
||||
for reaction in reactions {
|
||||
reactionMap[reaction.value] = reaction
|
||||
}
|
||||
|
||||
var sortedReactions: [AvailableReactions.Reaction] = []
|
||||
for emoji in order {
|
||||
if let reaction = reactionMap[emoji] {
|
||||
sortedReactions.append(reaction)
|
||||
}
|
||||
}
|
||||
|
||||
self.reactions = sortedReactions
|
||||
|
||||
self.scrollNode = ASScrollNode()
|
||||
self.tapNode = ASDisplayNode()
|
||||
@@ -123,6 +146,10 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.setup()
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.timer?.invalidate()
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
@@ -134,6 +161,8 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
@objc private func reactionTapped(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
self.previousInteractionTimestamp = CACurrentMediaTime()
|
||||
|
||||
guard self.animator == nil, self.scrollStartPosition == nil else {
|
||||
return
|
||||
}
|
||||
@@ -143,11 +172,42 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
self.scrollTo(index, playReaction: true, duration: 0.4)
|
||||
self.scrollTo(index, playReaction: true, immediately: true, duration: 0.4)
|
||||
}
|
||||
|
||||
func setVisible(_ visible: Bool) {
|
||||
if visible {
|
||||
self.animateIn()
|
||||
} else {
|
||||
self.scrollTo(0, playReaction: false, immediately: false, duration: 0.0, clockwise: false)
|
||||
self.timer?.invalidate()
|
||||
self.timer = nil
|
||||
|
||||
self.playingIndices.removeAll()
|
||||
self.standaloneReactionAnimation?.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
|
||||
func animateIn() {
|
||||
self.scrollTo(1, playReaction: true, duration: 0.5, clockwise: true)
|
||||
self.scrollTo(1, playReaction: true, immediately: false, duration: 0.5, clockwise: true)
|
||||
|
||||
if self.timer == nil {
|
||||
self.previousInteractionTimestamp = CACurrentMediaTime()
|
||||
self.timer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let currentTimestamp = CACurrentMediaTime()
|
||||
if currentTimestamp > strongSelf.previousInteractionTimestamp + 5.0 {
|
||||
var nextIndex = strongSelf.currentIndex - 1
|
||||
if nextIndex < 0 {
|
||||
nextIndex = strongSelf.reactions.count + nextIndex
|
||||
}
|
||||
strongSelf.scrollTo(nextIndex, playReaction: true, immediately: true, duration: 0.3, clockwise: true)
|
||||
strongSelf.previousInteractionTimestamp = currentTimestamp
|
||||
}
|
||||
}
|
||||
}, queue: Queue.mainQueue())
|
||||
self.timer?.start()
|
||||
}
|
||||
}
|
||||
|
||||
func animateOut() {
|
||||
@@ -156,7 +216,7 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func scrollTo(_ index: Int, playReaction: Bool, duration: Double, clockwise: Bool? = nil) {
|
||||
func scrollTo(_ index: Int, playReaction: Bool, immediately: Bool, duration: Double, clockwise: Bool? = nil) {
|
||||
guard index >= 0 && index < self.itemNodes.count else {
|
||||
return
|
||||
}
|
||||
@@ -184,25 +244,36 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
self.animator = DisplayLinkAnimator(duration: duration * UIView.animationDurationFactor(), from: 0.0, to: 1.0, update: { [weak self] t in
|
||||
let t = listViewAnimationCurveSystem(t)
|
||||
var updatedPosition = startPosition + change * t
|
||||
while updatedPosition >= 1.0 {
|
||||
updatedPosition -= 1.0
|
||||
if immediately {
|
||||
self.playReaction(index: index)
|
||||
}
|
||||
|
||||
if duration.isZero {
|
||||
self.currentPosition = newPosition
|
||||
if let size = self.validLayout {
|
||||
self.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
while updatedPosition < 0.0 {
|
||||
updatedPosition += 1.0
|
||||
}
|
||||
self?.currentPosition = updatedPosition
|
||||
if let size = self?.validLayout {
|
||||
self?.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
}, completion: { [weak self] in
|
||||
self?.animator = nil
|
||||
if playReaction {
|
||||
self?.playReaction()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.animator = DisplayLinkAnimator(duration: duration * UIView.animationDurationFactor(), from: 0.0, to: 1.0, update: { [weak self] t in
|
||||
let t = listViewAnimationCurveSystem(t)
|
||||
var updatedPosition = startPosition + change * t
|
||||
while updatedPosition >= 1.0 {
|
||||
updatedPosition -= 1.0
|
||||
}
|
||||
while updatedPosition < 0.0 {
|
||||
updatedPosition += 1.0
|
||||
}
|
||||
self?.currentPosition = updatedPosition
|
||||
if let size = self?.validLayout {
|
||||
self?.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
}, completion: { [weak self] in
|
||||
self?.animator = nil
|
||||
if playReaction && !immediately {
|
||||
self?.playReaction(index: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func setup() {
|
||||
@@ -240,14 +311,19 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.ignoreContentOffsetChange = false
|
||||
}
|
||||
|
||||
func playReaction() {
|
||||
let delta = self.positionDelta
|
||||
let index = max(0, Int(round(self.currentPosition / delta)) % self.itemNodes.count)
|
||||
func playReaction(index: Int?) {
|
||||
let index = index ?? max(0, Int(round(self.currentPosition / self.positionDelta)) % self.itemNodes.count)
|
||||
|
||||
guard !self.playingIndices.contains(index) else {
|
||||
return
|
||||
}
|
||||
|
||||
if let current = self.standaloneReactionAnimation, let dismiss = current.currentDismissAnimation {
|
||||
dismiss()
|
||||
current.currentDismissAnimation = nil
|
||||
self.playingIndices.removeAll()
|
||||
}
|
||||
|
||||
let reaction = self.reactions[index]
|
||||
let targetContainerNode = self.itemContainerNodes[index]
|
||||
let targetView = self.itemNodes[index].view
|
||||
@@ -284,10 +360,13 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
forceSmallEffectAnimation: true,
|
||||
targetView: targetView,
|
||||
addStandaloneReactionAnimation: nil,
|
||||
currentItemNode: self.itemNodes[index],
|
||||
completion: { [weak standaloneReactionAnimation, weak self] in
|
||||
standaloneReactionAnimation?.removeFromSupernode()
|
||||
self?.standaloneReactionAnimation = nil
|
||||
self?.playingIndices.remove(index)
|
||||
if self?.standaloneReactionAnimation === standaloneReactionAnimation {
|
||||
self?.standaloneReactionAnimation = nil
|
||||
self?.playingIndices.remove(index)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -301,6 +380,10 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if scrollView.isTracking {
|
||||
self.previousInteractionTimestamp = CACurrentMediaTime()
|
||||
}
|
||||
|
||||
guard !self.ignoreContentOffsetChange, let (startContentOffset, startPosition) = self.scrollStartPosition else {
|
||||
return
|
||||
}
|
||||
@@ -347,17 +430,21 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
||||
if !decelerate {
|
||||
self.previousInteractionTimestamp = CACurrentMediaTime()
|
||||
|
||||
self.resetScrollPosition()
|
||||
|
||||
let delta = self.positionDelta
|
||||
let index = max(0, Int(round(self.currentPosition / delta)) % self.itemNodes.count)
|
||||
self.scrollTo(index, playReaction: true, duration: 0.2)
|
||||
self.scrollTo(index, playReaction: true, immediately: true, duration: 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||||
self.previousInteractionTimestamp = CACurrentMediaTime()
|
||||
|
||||
self.resetScrollPosition()
|
||||
self.playReaction()
|
||||
self.playReaction(index: nil)
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
|
||||
@@ -936,7 +936,9 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
self.animateReactionSelection(context: context, theme: theme, reaction: reaction, avatarPeers: avatarPeers, playHaptic: playHaptic, isLarge: isLarge, forceSmallEffectAnimation: forceSmallEffectAnimation, targetView: targetView, addStandaloneReactionAnimation: addStandaloneReactionAnimation, currentItemNode: nil, completion: completion)
|
||||
}
|
||||
|
||||
func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionItem, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, forceSmallEffectAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, currentItemNode: ReactionNode?, completion: @escaping () -> Void) {
|
||||
public var currentDismissAnimation: (() -> Void)?
|
||||
|
||||
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, reaction: ReactionItem, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, forceSmallEffectAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, currentItemNode: ReactionNode?, completion: @escaping () -> Void) {
|
||||
guard let sourceSnapshotView = targetView.snapshotContentTree() else {
|
||||
completion()
|
||||
return
|
||||
@@ -955,12 +957,14 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
itemNode = ReactionNode(context: context, theme: theme, item: reaction)
|
||||
}
|
||||
self.itemNode = itemNode
|
||||
|
||||
if let targetView = targetView as? ReactionIconView, !isLarge {
|
||||
self.itemNodeIsEmbedded = true
|
||||
targetView.addSubnode(itemNode)
|
||||
} else {
|
||||
self.addSubnode(itemNode)
|
||||
|
||||
if !forceSmallEffectAnimation {
|
||||
if let targetView = targetView as? ReactionIconView, !isLarge {
|
||||
self.itemNodeIsEmbedded = true
|
||||
targetView.addSubnode(itemNode)
|
||||
} else {
|
||||
self.addSubnode(itemNode)
|
||||
}
|
||||
}
|
||||
|
||||
itemNode.expandedAnimationDidBegin = { [weak self, weak targetView] in
|
||||
@@ -975,7 +979,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
targetView.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
itemNode.isExtracted = true
|
||||
let selfTargetRect = self.view.convert(targetView.bounds, from: targetView)
|
||||
|
||||
@@ -1077,7 +1081,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var didBeginDismissAnimation = false
|
||||
let beginDismissAnimation: () -> Void = { [weak self] in
|
||||
if !didBeginDismissAnimation {
|
||||
@@ -1089,62 +1093,91 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
return
|
||||
}
|
||||
|
||||
if isLarge {
|
||||
strongSelf.animateFromItemNodeToReaction(itemNode: itemNode, targetView: targetView, hideNode: true, completion: {
|
||||
if let addStandaloneReactionAnimation = addStandaloneReactionAnimation {
|
||||
let standaloneReactionAnimation = StandaloneReactionAnimation()
|
||||
if forceSmallEffectAnimation {
|
||||
additionalAnimationNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak additionalAnimationNode] _ in
|
||||
additionalAnimationNode?.removeFromSupernode()
|
||||
})
|
||||
|
||||
mainAnimationCompleted = true
|
||||
intermediateCompletion()
|
||||
} else {
|
||||
if isLarge {
|
||||
strongSelf.animateFromItemNodeToReaction(itemNode: itemNode, targetView: targetView, hideNode: true, completion: {
|
||||
if let addStandaloneReactionAnimation = addStandaloneReactionAnimation {
|
||||
let standaloneReactionAnimation = StandaloneReactionAnimation()
|
||||
|
||||
addStandaloneReactionAnimation(standaloneReactionAnimation)
|
||||
|
||||
standaloneReactionAnimation.animateReactionSelection(
|
||||
context: itemNode.context,
|
||||
theme: itemNode.context.sharedContext.currentPresentationData.with({ $0 }).theme,
|
||||
reaction: itemNode.item,
|
||||
avatarPeers: avatarPeers,
|
||||
playHaptic: false,
|
||||
isLarge: false,
|
||||
targetView: targetView,
|
||||
addStandaloneReactionAnimation: nil,
|
||||
completion: { [weak standaloneReactionAnimation] in
|
||||
standaloneReactionAnimation?.removeFromSupernode()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
addStandaloneReactionAnimation(standaloneReactionAnimation)
|
||||
|
||||
standaloneReactionAnimation.animateReactionSelection(
|
||||
context: itemNode.context,
|
||||
theme: itemNode.context.sharedContext.currentPresentationData.with({ $0 }).theme,
|
||||
reaction: itemNode.item,
|
||||
avatarPeers: avatarPeers,
|
||||
playHaptic: false,
|
||||
isLarge: false,
|
||||
targetView: targetView,
|
||||
addStandaloneReactionAnimation: nil,
|
||||
completion: { [weak standaloneReactionAnimation] in
|
||||
standaloneReactionAnimation?.removeFromSupernode()
|
||||
}
|
||||
)
|
||||
mainAnimationCompleted = true
|
||||
intermediateCompletion()
|
||||
})
|
||||
} else {
|
||||
if let targetView = strongSelf.targetView {
|
||||
if let targetView = targetView as? ReactionIconView, !isLarge {
|
||||
targetView.imageView.isHidden = false
|
||||
} else {
|
||||
targetView.alpha = 1.0
|
||||
targetView.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
if strongSelf.itemNodeIsEmbedded {
|
||||
strongSelf.itemNode?.removeFromSupernode()
|
||||
}
|
||||
|
||||
mainAnimationCompleted = true
|
||||
intermediateCompletion()
|
||||
})
|
||||
} else {
|
||||
if let targetView = strongSelf.targetView {
|
||||
if let targetView = targetView as? ReactionIconView, !isLarge {
|
||||
targetView.imageView.isHidden = false
|
||||
} else {
|
||||
targetView.alpha = 1.0
|
||||
targetView.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
if strongSelf.itemNodeIsEmbedded {
|
||||
strongSelf.itemNode?.removeFromSupernode()
|
||||
}
|
||||
|
||||
mainAnimationCompleted = true
|
||||
intermediateCompletion()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.currentDismissAnimation = beginDismissAnimation
|
||||
|
||||
let maybeBeginDismissAnimation: () -> Void = {
|
||||
if mainAnimationCompleted && additionalAnimationCompleted {
|
||||
beginDismissAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
if forceSmallEffectAnimation {
|
||||
itemNode.mainAnimationCompletion = {
|
||||
mainAnimationCompleted = true
|
||||
maybeBeginDismissAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
additionalAnimationNode.completed = { _ in
|
||||
additionalAnimationCompleted = true
|
||||
intermediateCompletion()
|
||||
beginDismissAnimation()
|
||||
if forceSmallEffectAnimation {
|
||||
maybeBeginDismissAnimation()
|
||||
} else {
|
||||
beginDismissAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
additionalAnimationNode.visibility = true
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0, execute: {
|
||||
beginDismissAnimation()
|
||||
})
|
||||
if !forceSmallEffectAnimation {
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0, execute: {
|
||||
beginDismissAnimation()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func animateFromItemNodeToReaction(itemNode: ReactionNode, targetView: UIView, hideNode: Bool, completion: @escaping () -> Void) {
|
||||
|
||||
@@ -45,6 +45,7 @@ protocol ReactionItemNode: ASDisplayNode {
|
||||
public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
let context: AccountContext
|
||||
let item: ReactionItem
|
||||
private let hasAppearAnimation: Bool
|
||||
|
||||
private var animateInAnimationNode: AnimatedStickerNode?
|
||||
private let staticAnimationNode: AnimatedStickerNode
|
||||
@@ -67,6 +68,7 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
public init(context: AccountContext, theme: PresentationTheme, item: ReactionItem, hasAppearAnimation: Bool = true) {
|
||||
self.context = context
|
||||
self.item = item
|
||||
self.hasAppearAnimation = hasAppearAnimation
|
||||
|
||||
self.staticAnimationNode = AnimatedStickerNode()
|
||||
|
||||
@@ -113,6 +115,8 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
public var mainAnimationCompletion: (() -> Void)?
|
||||
|
||||
public func updateLayout(size: CGSize, isExpanded: Bool, largeExpanded: Bool, isPreviewing: Bool, transition: ContainedViewLayoutTransition) {
|
||||
let intrinsicSize = size
|
||||
|
||||
@@ -130,7 +134,9 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
|
||||
let expandedAnimationFrame = animationFrame
|
||||
|
||||
if isExpanded, self.animationNode == nil {
|
||||
if isExpanded && !self.hasAppearAnimation {
|
||||
self.staticAnimationNode.play(fromIndex: 0)
|
||||
} else if isExpanded, self.animationNode == nil {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
animationNode.automaticallyLoadFirstFrame = true
|
||||
self.animationNode = animationNode
|
||||
@@ -143,6 +149,9 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
self?.expandedAnimationDidBegin?()
|
||||
}
|
||||
}
|
||||
animationNode.completed = { [weak self] _ in
|
||||
self?.mainAnimationCompletion?()
|
||||
}
|
||||
|
||||
if largeExpanded {
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation.resource), width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation.resource.id)))
|
||||
@@ -274,7 +283,11 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
||||
if self.animationNode == nil {
|
||||
self.didSetupStillAnimation = true
|
||||
|
||||
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation.resource), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation.resource.id)))
|
||||
if !self.hasAppearAnimation {
|
||||
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.largeListAnimation.resource), width: Int(expandedAnimationFrame.width * 2.0), height: Int(expandedAnimationFrame.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.largeListAnimation.resource.id)))
|
||||
} else {
|
||||
self.staticAnimationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.item.stillAnimation.resource), width: Int(animationDisplaySize.width * 2.0), height: Int(animationDisplaySize.height * 2.0), playbackMode: .still(.start), mode: .direct(cachePathPrefix: self.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(self.item.stillAnimation.resource.id)))
|
||||
}
|
||||
self.staticAnimationNode.position = animationFrame.center
|
||||
self.staticAnimationNode.bounds = CGRect(origin: CGPoint(), size: animationFrame.size)
|
||||
self.staticAnimationNode.updateLayout(size: animationFrame.size)
|
||||
|
||||
@@ -1044,11 +1044,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if !reaction.isEnabled {
|
||||
continue
|
||||
}
|
||||
if reaction.isPremium && !hasPremium {
|
||||
hasPremiumPlaceholder = true
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
switch allowedReactions {
|
||||
case let .set(set):
|
||||
if !set.contains(reaction.value) {
|
||||
@@ -1057,6 +1053,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case .all:
|
||||
break
|
||||
}
|
||||
|
||||
if reaction.isPremium && !hasPremium {
|
||||
hasPremiumPlaceholder = true
|
||||
continue
|
||||
}
|
||||
|
||||
actions.reactionItems.append(.reaction(ReactionItem(
|
||||
reaction: ReactionItem.Reaction(rawValue: reaction.value),
|
||||
appearAnimation: reaction.appearAnimation,
|
||||
|
||||
Reference in New Issue
Block a user