mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Don't autoplay previously seen animated emoji on repeated appearance on screen
This commit is contained in:
parent
35ef08fc06
commit
7d434ac5c9
@ -306,6 +306,9 @@ final class AnimatedStickerNode: ASDisplayNode {
|
||||
private let fetchDisposable = MetaDisposable()
|
||||
private let eventsNode: AnimatedStickerNodeDisplayEvents
|
||||
|
||||
var shouldAutoPlay: () -> Bool = {
|
||||
return true
|
||||
}
|
||||
var started: () -> Void = {}
|
||||
var reportedStarted = false
|
||||
|
||||
@ -407,7 +410,7 @@ final class AnimatedStickerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private func updateIsPlaying() {
|
||||
let isPlaying = self.visibility && self.isDisplaying
|
||||
let isPlaying = self.visibility && self.isDisplaying && self.shouldAutoPlay()
|
||||
if self.isPlaying != isPlaying {
|
||||
self.isPlaying = isPlaying
|
||||
if isPlaying {
|
||||
@ -454,6 +457,7 @@ final class AnimatedStickerNode: ASDisplayNode {
|
||||
return
|
||||
}
|
||||
if !strongSelf.reportedStarted {
|
||||
strongSelf.reportedStarted = true
|
||||
strongSelf.started()
|
||||
}
|
||||
})
|
||||
|
||||
@ -123,6 +123,7 @@ public final class ChatControllerInteraction {
|
||||
var pollActionState: ChatInterfacePollActionState
|
||||
var stickerSettings: ChatInterfaceStickerSettings
|
||||
var searchTextHighightState: String?
|
||||
var seenOneTimeAnimatedMedia = Set<MessageId>()
|
||||
|
||||
init(openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendCurrentMessage: @escaping (Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool, ASDisplayNode, CGRect) -> Bool, sendGif: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool) -> Void, requestMessageActionUrlAuth: @escaping (String, MessageId, Int32) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction, Message?) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> Bool, navigateToFirstDateMessage: @escaping(Int32) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId) -> Void, requestSelectMessagePollOption: @escaping (MessageId, Data) -> Void, openAppStorePage: @escaping () -> Void, displayMessageTooltip: @escaping (MessageId, String, ASDisplayNode?, CGRect?) -> Void, seekToTimecode: @escaping (Message, Double, Bool) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings) {
|
||||
self.openMessage = openMessage
|
||||
|
||||
@ -51,7 +51,26 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
super.init(layerBacked: false)
|
||||
|
||||
self.animationNode.started = { [weak self] in
|
||||
self?.imageNode.alpha = 0.0
|
||||
if let strongSelf = self {
|
||||
strongSelf.imageNode.alpha = 0.0
|
||||
|
||||
if let item = strongSelf.item {
|
||||
if let _ = strongSelf.emojiFile {
|
||||
item.controllerInteraction.seenOneTimeAnimatedMedia.insert(item.message.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.animationNode.shouldAutoPlay = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let item = strongSelf.item {
|
||||
if let _ = strongSelf.emojiFile {
|
||||
return !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
self.imageNode.displaysAsynchronously = false
|
||||
@ -171,9 +190,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
} else if let emojiFile = self.emojiFile {
|
||||
isEmoji = true
|
||||
file = emojiFile
|
||||
if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce {
|
||||
playbackMode = .once
|
||||
}
|
||||
playbackMode = .once
|
||||
}
|
||||
|
||||
if let file = file {
|
||||
@ -665,29 +682,27 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
if self.telegramFile != nil {
|
||||
let _ = item.controllerInteraction.openMessage(item.message, .default)
|
||||
} else if let _ = self.emojiFile {
|
||||
if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce {
|
||||
if self.animationNode.playIfNeeded() {
|
||||
if self.item?.message.text == "❤️" {
|
||||
let hapticFeedback: HapticFeedback
|
||||
if let currentHapticFeedback = self.hapticFeedback {
|
||||
hapticFeedback = currentHapticFeedback
|
||||
} else {
|
||||
hapticFeedback = HapticFeedback()
|
||||
self.hapticFeedback = hapticFeedback
|
||||
}
|
||||
hapticFeedback.prepareImpact()
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
Queue.mainQueue().after(0.78) {
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
Queue.mainQueue().after(0.78) {
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
}
|
||||
if self.animationNode.playIfNeeded() {
|
||||
if self.item?.message.text == "❤️" {
|
||||
let hapticFeedback: HapticFeedback
|
||||
if let currentHapticFeedback = self.hapticFeedback {
|
||||
hapticFeedback = currentHapticFeedback
|
||||
} else {
|
||||
hapticFeedback = HapticFeedback()
|
||||
self.hapticFeedback = hapticFeedback
|
||||
}
|
||||
hapticFeedback.prepareImpact()
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
Queue.mainQueue().after(0.78) {
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
Queue.mainQueue().after(0.78) {
|
||||
hapticFeedback.impact(.medium)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
hapticFeedback.impact(.light)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
case resetBiometricsData(PresentationTheme)
|
||||
case optimizeDatabase(PresentationTheme)
|
||||
case photoPreview(PresentationTheme, Bool)
|
||||
case playAnimatedEmojiOnce(PresentationTheme, Bool)
|
||||
case exportTheme(PresentationTheme)
|
||||
case versionInfo(PresentationTheme)
|
||||
|
||||
@ -71,7 +70,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return DebugControllerSection.logging.rawValue
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .playAnimatedEmojiOnce, .exportTheme:
|
||||
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .exportTheme:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .versionInfo:
|
||||
return DebugControllerSection.info.rawValue
|
||||
@ -120,12 +119,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return 18
|
||||
case .photoPreview:
|
||||
return 19
|
||||
case .playAnimatedEmojiOnce:
|
||||
return 20
|
||||
case .exportTheme:
|
||||
return 21
|
||||
return 20
|
||||
case .versionInfo:
|
||||
return 22
|
||||
return 21
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,16 +469,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .playAnimatedEmojiOnce(theme, value):
|
||||
return ItemListSwitchItem(theme: theme, title: "Play Emoji Once", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
|
||||
settings.playAnimatedEmojiOnce = value
|
||||
return settings
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .exportTheme(theme):
|
||||
return ItemListActionItem(theme: theme, title: "Export Theme", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||
guard let context = arguments.context else {
|
||||
@ -549,7 +536,6 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS
|
||||
entries.append(.resetHoles(presentationData.theme))
|
||||
entries.append(.optimizeDatabase(presentationData.theme))
|
||||
entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos))
|
||||
entries.append(.playAnimatedEmojiOnce(presentationData.theme, experimentalSettings.playAnimatedEmojiOnce))
|
||||
|
||||
entries.append(.versionInfo(presentationData.theme))
|
||||
|
||||
|
||||
@ -7,18 +7,16 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
||||
public var skipReadHistory: Bool
|
||||
public var crashOnLongQueries: Bool
|
||||
public var chatListPhotos: Bool
|
||||
public var playAnimatedEmojiOnce: Bool
|
||||
|
||||
public static var defaultSettings: ExperimentalUISettings {
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, playAnimatedEmojiOnce: true)
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false)
|
||||
}
|
||||
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, playAnimatedEmojiOnce: Bool) {
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool) {
|
||||
self.keepChatNavigationStack = keepChatNavigationStack
|
||||
self.skipReadHistory = skipReadHistory
|
||||
self.crashOnLongQueries = crashOnLongQueries
|
||||
self.chatListPhotos = chatListPhotos
|
||||
self.playAnimatedEmojiOnce = playAnimatedEmojiOnce
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
@ -26,7 +24,6 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
||||
self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0
|
||||
self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0
|
||||
self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0
|
||||
self.playAnimatedEmojiOnce = decoder.decodeInt32ForKey("playAnimatedEmojiOnce", orElse: 1) != 0
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -34,7 +31,6 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
||||
encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory")
|
||||
encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries")
|
||||
encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos")
|
||||
encoder.encodeInt32(self.playAnimatedEmojiOnce ? 1 : 0, forKey: "playAnimatedEmojiOnce")
|
||||
}
|
||||
|
||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user