mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Story improvements
This commit is contained in:
parent
54375b7682
commit
6513c9c6e6
@ -545,21 +545,26 @@ public final class DrawingStickerEntityView: DrawingEntityView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reactionContextNode.premiumReactionsSelected = { [weak self] file in
|
reactionContextNode.premiumReactionsSelected = { [weak self] file in
|
||||||
guard let self, let file else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = self.context
|
if let file {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let context = self.context
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, loop: true, title: nil, text: presentationData.strings.Story_Editor_TooltipPremiumReaction, undoText: nil, customAction: nil), elevatedLayout: true, animateInAsReplacement: false, blurred: true, action: { [weak self] action in
|
|
||||||
if case .info = action, let self {
|
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, loop: true, title: nil, text: presentationData.strings.Story_Editor_TooltipPremiumReaction, undoText: nil, customAction: nil), elevatedLayout: true, animateInAsReplacement: false, blurred: true, action: { [weak self] action in
|
||||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .storiesExpirationDurations, forceDark: true, dismissed: nil)
|
if case .info = action, let self {
|
||||||
self.containerView?.push(controller)
|
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .storiesExpirationDurations, forceDark: true, dismissed: nil)
|
||||||
}
|
self.containerView?.push(controller)
|
||||||
return false
|
}
|
||||||
})
|
return false
|
||||||
self.containerView?.present(controller)
|
})
|
||||||
|
self.containerView?.present(controller)
|
||||||
|
} else {
|
||||||
|
let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .storiesExpirationDurations, forceDark: true, dismissed: nil)
|
||||||
|
self.containerView?.push(controller)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let anchorRect = self.convert(self.bounds, to: superview).offsetBy(dx: 0.0, dy: -20.0)
|
let anchorRect = self.convert(self.bounds, to: superview).offsetBy(dx: 0.0, dy: -20.0)
|
||||||
|
|||||||
@ -2621,70 +2621,99 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
|
|
||||||
var additionalCachePathPrefix: String?
|
var additionalCachePathPrefix: String?
|
||||||
additionalCachePathPrefix = itemNode.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimation.resource.id)
|
additionalCachePathPrefix = itemNode.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimation.resource.id)
|
||||||
//#if DEBUG
|
|
||||||
additionalCachePathPrefix = nil
|
additionalCachePathPrefix = nil
|
||||||
//#endif
|
|
||||||
|
|
||||||
additionalAnimationNodeValue.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimation.resource), width: Int(effectFrame.width * 1.33), height: Int(effectFrame.height * 1.33), playbackMode: .once, mode: .direct(cachePathPrefix: additionalCachePathPrefix))
|
additionalAnimationNodeValue.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimation.resource), width: Int(effectFrame.width * 1.33), height: Int(effectFrame.height * 1.33), playbackMode: .once, mode: .direct(cachePathPrefix: additionalCachePathPrefix))
|
||||||
additionalAnimationNodeValue.frame = effectFrame
|
additionalAnimationNodeValue.frame = effectFrame
|
||||||
additionalAnimationNodeValue.updateLayout(size: effectFrame.size)
|
additionalAnimationNodeValue.updateLayout(size: effectFrame.size)
|
||||||
self.addSubnode(additionalAnimationNodeValue)
|
self.addSubnode(additionalAnimationNodeValue)
|
||||||
} else if itemNode.item.isCustom {
|
} else if itemNode.item.isCustom {
|
||||||
additionalAnimationNode = nil
|
|
||||||
|
|
||||||
var effectData: Data?
|
var effectURL: URL?
|
||||||
if let genericReactionEffect = self.genericReactionEffect, let data = try? Data(contentsOf: URL(fileURLWithPath: genericReactionEffect)) {
|
if let genericReactionEffect = self.genericReactionEffect {
|
||||||
effectData = TGGUnzipData(data, 5 * 1024 * 1024) ?? data
|
effectURL = URL(fileURLWithPath: genericReactionEffect)
|
||||||
} else {
|
} else {
|
||||||
if let url = getAppBundle().url(forResource: "generic_reaction_small_effect", withExtension: "json") {
|
if let url = getAppBundle().url(forResource: "generic_reaction_small_effect", withExtension: "json") {
|
||||||
effectData = try? Data(contentsOf: url)
|
effectURL = url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let effectData = effectData, let composition = try? Animation.from(data: effectData) {
|
if "".isEmpty, let effectURL {
|
||||||
let view = AnimationView(animation: composition, configuration: LottieConfiguration(renderingEngine: .mainThread, decodingStrategy: .codable))
|
let additionalAnimationNodeValue: AnimatedStickerNode
|
||||||
view.animationSpeed = 1.0
|
if self.useDirectRendering {
|
||||||
view.backgroundColor = nil
|
additionalAnimationNodeValue = DirectAnimatedStickerNode()
|
||||||
view.isOpaque = false
|
} else {
|
||||||
|
additionalAnimationNodeValue = DefaultAnimatedStickerNodeImpl()
|
||||||
if incomingMessage {
|
|
||||||
view.layer.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
|
|
||||||
}
|
}
|
||||||
|
additionalAnimationNode = additionalAnimationNodeValue
|
||||||
|
|
||||||
genericAnimationView = view
|
if isLarge && !forceSmallEffectAnimation {
|
||||||
|
if incomingMessage {
|
||||||
let animationCache = itemNode.context.animationCache
|
additionalAnimationNodeValue.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
|
||||||
let animationRenderer = itemNode.context.animationRenderer
|
|
||||||
|
|
||||||
for i in 1 ... 7 {
|
|
||||||
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
|
|
||||||
for animationLayer in allLayers {
|
|
||||||
let baseItemLayer = InlineStickerItemLayer(
|
|
||||||
context: itemNode.context,
|
|
||||||
userLocation: .other,
|
|
||||||
attemptSynchronousLoad: false,
|
|
||||||
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
|
|
||||||
file: itemNode.item.listAnimation,
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view.frame = effectFrame.insetBy(dx: -20.0, dy: -20.0)//.offsetBy(dx: incomingMessage ? 22.0 : -22.0, dy: 0.0)
|
additionalAnimationNodeValue.setup(source: AnimatedStickerNodeLocalFileSource(name: effectURL.path), width: Int(effectFrame.width * 1.33), height: Int(effectFrame.height * 1.33), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||||
self.view.addSubview(view)
|
additionalAnimationNodeValue.frame = effectFrame
|
||||||
|
additionalAnimationNodeValue.updateLayout(size: effectFrame.size)
|
||||||
|
self.addSubnode(additionalAnimationNodeValue)
|
||||||
|
} else {
|
||||||
|
additionalAnimationNode = nil
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if incomingMessage {
|
||||||
|
view.layer.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
genericAnimationView = view
|
||||||
|
|
||||||
|
let animationCache = itemNode.context.animationCache
|
||||||
|
let animationRenderer = itemNode.context.animationRenderer
|
||||||
|
|
||||||
|
for i in 1 ... 7 {
|
||||||
|
let allLayers = view.allLayers(forKeypath: AnimationKeypath(keypath: "placeholder_\(i)"))
|
||||||
|
for animationLayer in allLayers {
|
||||||
|
let baseItemLayer = InlineStickerItemLayer(
|
||||||
|
context: itemNode.context,
|
||||||
|
userLocation: .other,
|
||||||
|
attemptSynchronousLoad: false,
|
||||||
|
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
|
||||||
|
file: itemNode.item.listAnimation,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.frame = effectFrame.insetBy(dx: -20.0, dy: -20.0)//.offsetBy(dx: incomingMessage ? 22.0 : -22.0, dy: 0.0)
|
||||||
|
self.view.addSubview(view)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
additionalAnimationNode = nil
|
additionalAnimationNode = nil
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public final class AnimatedStickerNodeLocalFileSource: AnimatedStickerNodeSource
|
|||||||
} else if let path = getAppBundle().path(forResource: self.name, ofType: "json") {
|
} else if let path = getAppBundle().path(forResource: self.name, ofType: "json") {
|
||||||
return path
|
return path
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return self.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -584,6 +584,18 @@ public final class PeerStoryListContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for mediaArea in mappedItem.mediaAreas {
|
||||||
|
if case let .reaction(_, reaction, _) = mediaArea {
|
||||||
|
if case let .custom(fileId) = reaction {
|
||||||
|
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
|
||||||
|
if allEntityFiles[mediaId] == nil {
|
||||||
|
if let file = transaction.getMedia(mediaId) as? TelegramMediaFile {
|
||||||
|
allEntityFiles[file.fileId] = file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -563,7 +563,11 @@ public final class PeerListItemComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let availableTextWidth = availableSize.width - leftInset - rightInset
|
let availableTextWidth = availableSize.width - leftInset - rightInset
|
||||||
let titleAvailableWidth = component.style == .compact ? availableTextWidth * 0.7 : availableSize.width - leftInset - rightInset
|
var titleAvailableWidth = component.style == .compact ? availableTextWidth * 0.7 : availableSize.width - leftInset - rightInset
|
||||||
|
if case .none = component.rightAccessory {
|
||||||
|
} else {
|
||||||
|
titleAvailableWidth -= 20.0
|
||||||
|
}
|
||||||
let titleSize = self.title.update(
|
let titleSize = self.title.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
|
|||||||
@ -1394,7 +1394,6 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
|
|
||||||
itemSetView.view.parentState = self.state
|
itemSetView.view.parentState = self.state
|
||||||
|
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
|
||||||
let _ = itemSetView.view.update(
|
let _ = itemSetView.view.update(
|
||||||
transition: itemSetTransition,
|
transition: itemSetTransition,
|
||||||
component: AnyComponent(StoryItemSetContainerComponent(
|
component: AnyComponent(StoryItemSetContainerComponent(
|
||||||
@ -1538,7 +1537,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||||
if itemSetView.superview == nil {
|
if itemSetView.superview == nil {
|
||||||
self.addSubview(itemSetView)
|
self.addSubview(itemSetView)
|
||||||
print("init time: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
|
//print("init time: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
|
||||||
}
|
}
|
||||||
if itemSetComponentView.superview == nil {
|
if itemSetComponentView.superview == nil {
|
||||||
itemSetView.tintLayer.isDoubleSided = false
|
itemSetView.tintLayer.isDoubleSided = false
|
||||||
|
|||||||
@ -1574,6 +1574,9 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
self.visibleItems.removeValue(forKey: itemId)
|
self.visibleItems.removeValue(forKey: itemId)
|
||||||
visibleItem.contentContainerView.removeFromSuperview()
|
visibleItem.contentContainerView.removeFromSuperview()
|
||||||
visibleItem.unclippedContainerView.removeFromSuperview()
|
visibleItem.unclippedContainerView.removeFromSuperview()
|
||||||
|
visibleItem.contentTintLayer.removeFromSuperlayer()
|
||||||
|
visibleItem.footerPanel?.view?.removeFromSuperview()
|
||||||
|
visibleItem.contentViewsShadowView?.removeFromSuperview()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
itemTransition.setBounds(view: visibleItem.contentContainerView, bounds: CGRect(origin: CGPoint(), size: itemLayout.contentFrame.size))
|
itemTransition.setBounds(view: visibleItem.contentContainerView, bounds: CGRect(origin: CGPoint(), size: itemLayout.contentFrame.size))
|
||||||
|
|||||||
@ -3328,7 +3328,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
view.standaloneReactionAnimation = nil
|
view.standaloneReactionAnimation = nil
|
||||||
|
|
||||||
let standaloneReactionAnimationView = standaloneReactionAnimation.view
|
let standaloneReactionAnimationView = standaloneReactionAnimation.view
|
||||||
standaloneReactionAnimation.view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak standaloneReactionAnimationView] _ in
|
standaloneReactionAnimation.view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak standaloneReactionAnimationView] _ in
|
||||||
standaloneReactionAnimationView?.removeFromSuperview()
|
standaloneReactionAnimationView?.removeFromSuperview()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user