diff --git a/submodules/TelegramCore/Sources/State/PeerInputActivity.swift b/submodules/TelegramCore/Sources/State/PeerInputActivity.swift index f90ffa483d..2f761b47a7 100644 --- a/submodules/TelegramCore/Sources/State/PeerInputActivity.swift +++ b/submodules/TelegramCore/Sources/State/PeerInputActivity.swift @@ -26,6 +26,9 @@ public struct EmojiInteraction: Equatable { guard let item = decodedData as? [String: Any] else { return nil } + guard let version = item["v"] as? Int, version == 1 else { + return nil + } guard let animationsArray = item["a"] as? [Any] else { return nil } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 3e41340cf0..8142ce705e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1354,6 +1354,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } func playEmojiInteraction(_ interaction: EmojiInteraction) { + guard interaction.animations.count <= 7 else { + return + } + var hapticFeedback: HapticFeedback if let current = self.hapticFeedback { hapticFeedback = current @@ -1366,21 +1370,31 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let existingHaptic = self.haptic, existingHaptic.active { playHaptic = false } - hapticFeedback.prepareTap() - + hapticFeedback.prepareImpact(.light) + hapticFeedback.prepareImpact(.medium) + + var index = 0 for animation in interaction.animations { if animation.timeOffset > 0.0 { Queue.mainQueue().after(Double(animation.timeOffset)) { self.playAdditionalAnimation(index: animation.index) if playHaptic { - hapticFeedback.tap() + let style: ImpactHapticFeedbackStyle + if index == 1 { + style = .medium + } else { + style = [.light, .medium].randomElement() ?? .medium + } + hapticFeedback.impact(style) } + index += 1 } } else { self.playAdditionalAnimation(index: animation.index) if playHaptic { - hapticFeedback.tap() + hapticFeedback.impact(interaction.animations.count > 1 ? .light : .medium) } + index += 1 } } } @@ -1556,8 +1570,32 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { firstScalar = UnicodeScalar(heart)! } return .optionalAction({ + var haptic: EmojiHaptic? + if let current = self.haptic { + haptic = current + } else { + if firstScalar.value == heart { + haptic = HeartbeatHaptic() + } else if firstScalar.value == coffin { + haptic = CoffinHaptic() + } else if firstScalar.value == peach { + haptic = PeachHaptic() + } + haptic?.enabled = true + self.haptic = haptic + } + if let animationItems = item.associatedData.additionalAnimatedEmojiStickers[originalTextEmoji] { let syncAnimations = item.message.id.peerId.namespace == Namespaces.Peer.CloudUser + let playHaptic = haptic == nil + + var hapticFeedback: HapticFeedback + if let current = self.hapticFeedback { + hapticFeedback = current + } else { + hapticFeedback = HapticFeedback() + self.hapticFeedback = hapticFeedback + } if syncAnimations { self.startAdditionalAnimationsCommitTimer() @@ -1572,11 +1610,25 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { availableAnimations.removeValue(forKey: previousIndex) } if let (_, previousTimestamp) = previousAnimation { - delay = min(0.2, max(0.0, previousTimestamp + 0.2 - timestamp)) + delay = min(0.15, max(0.0, previousTimestamp + 0.15 - timestamp)) } if let index = availableAnimations.randomElement()?.0 { if delay > 0.0 { Queue.mainQueue().after(delay) { + if playHaptic { + if previousAnimation == nil { + hapticFeedback.impact(.light) + } else { + let style: ImpactHapticFeedbackStyle + if self.enqueuedAdditionalAnimations.count == 1 { + style = .medium + } else { + style = [.light, .medium].randomElement() ?? .medium + } + hapticFeedback.impact(style) + } + } + if syncAnimations { self.enqueuedAdditionalAnimations.append((index, timestamp + delay)) } @@ -1587,6 +1639,20 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } } else { + if playHaptic { + if previousAnimation == nil { + hapticFeedback.impact(.light) + } else { + let style: ImpactHapticFeedbackStyle + if self.enqueuedAdditionalAnimations.count == 1 { + style = .medium + } else { + style = [.light, .medium].randomElement() ?? .medium + } + hapticFeedback.impact(style) + } + } + if syncAnimations { self.enqueuedAdditionalAnimations.append((index, timestamp)) } @@ -1615,22 +1681,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { strongSelf.mediaStatusDisposable.set((mediaPlayer.status |> deliverOnMainQueue).start(next: { [weak self, weak animationNode] status in if let strongSelf = self { - - var haptic: EmojiHaptic? - if let current = strongSelf.haptic { - haptic = current - } else { - if firstScalar.value == heart { - haptic = HeartbeatHaptic() - } else if firstScalar.value == coffin { - haptic = CoffinHaptic() - } else if firstScalar.value == peach { - haptic = PeachHaptic() - } - haptic?.enabled = true - strongSelf.haptic = haptic - } - if let haptic = haptic, !haptic.active { haptic.start(time: 0.0) }