diff --git a/submodules/RLottie/Sources/LottieInstance.mm b/submodules/RLottie/Sources/LottieInstance.mm index 0b567f0dd6..e1859ef694 100644 --- a/submodules/RLottie/Sources/LottieInstance.mm +++ b/submodules/RLottie/Sources/LottieInstance.mm @@ -31,7 +31,7 @@ _dimensions = CGSizeMake(width, height); - if ((_frameRate > 60) || _animation->duration() > 4.5) { + if ((_frameRate > 60) || _animation->duration() > 7.0) { return nil; } } diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index 733e2374a5..a4a56c95d3 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -82,12 +82,14 @@ private final class AnimatedStickerFrame { let type: AnimationRendererFrameType let width: Int let height: Int + let isLastFrame: Bool - init(data: Data, type: AnimationRendererFrameType, width: Int, height: Int) { + init(data: Data, type: AnimationRendererFrameType, width: Int, height: Int, isLastFrame: Bool) { self.data = data self.type = type self.width = width self.height = height + self.isLastFrame = isLastFrame } } @@ -162,6 +164,7 @@ private final class AnimatedStickerCachedFrameSource: AnimatedStickerFrameSource func takeFrame() -> AnimatedStickerFrame { var frameData: Data? + var isLastFrame = false let dataLength = self.data.count let decodeBufferLength = self.decodeBuffer.count @@ -192,6 +195,7 @@ private final class AnimatedStickerCachedFrameSource: AnimatedStickerFrameSource self.offset += Int(frameLength) if self.offset == dataLength { + isLastFrame = true self.offset = self.initialOffset self.frameBuffer.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in memset(bytes, 0, frameBufferLength) @@ -199,7 +203,7 @@ private final class AnimatedStickerCachedFrameSource: AnimatedStickerFrameSource } } - return AnimatedStickerFrame(data: frameData!, type: .yuva, width: self.width, height: self.height) + return AnimatedStickerFrame(data: frameData!, type: .yuva, width: self.width, height: self.height, isLastFrame: isLastFrame) } } @@ -243,7 +247,7 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource memset(bytes, 0, self.width * self.height * 4) self.animation.renderFrame(with: Int32(frameIndex), into: bytes, width: Int32(self.width), height: Int32(self.height)) } - return AnimatedStickerFrame(data: frameData, type: .argb, width: self.width, height: self.height) + return AnimatedStickerFrame(data: frameData, type: .argb, width: self.width, height: self.height, isLastFrame: frameIndex == self.frameCount) } } @@ -434,6 +438,10 @@ final class AnimatedStickerNode: ASDisplayNode { strongSelf.started() } }) + if case .once = strongSelf.playbackMode, frame.isLastFrame { + strongSelf.stop() + strongSelf.isPlaying = false + } } } frameQueue.with { frameQueue in diff --git a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift index d61b285553..f2f180eacb 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift @@ -892,7 +892,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi return current } - if let updateRank = updateRank, updateRank.count > rankMaxLength { + if let updateRank = updateRank, updateRank.count > rankMaxLength || updateRank.containsEmoji { errorImpl?() return } @@ -928,6 +928,10 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi } let effectiveRank = updateRank ?? currentRank + if effectiveRank?.containsEmoji ?? false { + errorImpl?() + return + } if let updateFlags = updateFlags { updateState { current in @@ -961,7 +965,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi return current } - if let updateRank = updateRank, updateRank.count > rankMaxLength { + if let updateRank = updateRank, updateRank.count > rankMaxLength || updateRank.containsEmoji { errorImpl?() return } @@ -1014,7 +1018,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi return current } - if let updateRank = updateRank, updateRank.count > rankMaxLength { + if let updateRank = updateRank, updateRank.count > rankMaxLength || updateRank.containsEmoji { errorImpl?() return } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index fda6d0d21d..0eab5d0e7d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -153,11 +153,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { return } - let isPlaying = self.visibilityStatus && item.controllerInteraction.stickerSettings.loopAnimatedStickers + let isPlaying = self.visibilityStatus if self.isPlaying != isPlaying { self.isPlaying = isPlaying self.animationNode.visibility = isPlaying - if let item = self.item, isPlaying, !self.didSetUpAnimationNode { + if self.isPlaying && !self.didSetUpAnimationNode { self.didSetUpAnimationNode = true var telegramFile: TelegramMediaFile? for media in item.message.media { @@ -166,11 +166,19 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { break } } - + if let telegramFile = telegramFile { - self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: 384, height: 384, mode: .cached) + var playbackMode: AnimatedStickerPlaybackMode = .loop + if !item.controllerInteraction.stickerSettings.loopAnimatedStickers { + playbackMode = .once + } + self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: 384, height: 384, playbackMode: playbackMode, mode: .cached) } else if let emojiResource = self.emojiResource { - self.animationNode.setup(account: item.context.account, resource: emojiResource, width: 384, height: 384, mode: .cached) + var playbackMode: AnimatedStickerPlaybackMode = .loop + if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { + playbackMode = .once + } + self.animationNode.setup(account: item.context.account, resource: emojiResource, width: 384, height: 384, playbackMode: playbackMode, mode: .cached) } } } diff --git a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift index 6ac1668cf7..43b3567ceb 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift @@ -1,6 +1,7 @@ import Foundation import UIKit import AsyncDisplayKit +import SwiftSignalKit import Display import Postbox import TelegramCore @@ -44,7 +45,6 @@ private final class ActionSheetItemNode: ASDisplayNode { super.init() - self.addSubnode(self.separatorNode) self.addSubnode(self.highlightedBackgroundNode) self.addSubnode(self.titleNode) self.addSubnode(self.iconNode) @@ -389,6 +389,15 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, completedEffect = true intermediateCompletion() }) + + Queue.mainQueue().after(0.7) { + completedAlpha = true + completedButton = true + completedBubble = true + completedEffect = true + intermediateCompletion() + } + self.dimNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) self.contentContainerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in }) diff --git a/submodules/TelegramUI/TelegramUI/GlobalExperimentalSettings.swift b/submodules/TelegramUI/TelegramUI/GlobalExperimentalSettings.swift index 54dfa899e6..143bfa6a53 100644 --- a/submodules/TelegramUI/TelegramUI/GlobalExperimentalSettings.swift +++ b/submodules/TelegramUI/TelegramUI/GlobalExperimentalSettings.swift @@ -3,5 +3,4 @@ import Foundation public struct GlobalExperimentalSettings { public static var isAppStoreBuild: Bool = false public static var enableFeed: Bool = false - public static var animatedStickers: Bool = false }