Adjust message dissolve

This commit is contained in:
Isaac 2023-12-19 20:12:18 +04:00
parent 29728db54a
commit 64ca79a475
5 changed files with 62 additions and 90 deletions

View File

@ -5464,4 +5464,13 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
return (image, self.backgroundNode.frame)
}
public func isServiceLikeMessage() -> Bool {
for contentNode in self.contentNodes {
if contentNode is ChatMessageActionBubbleContentNode {
return true
}
}
return false
}
}

View File

@ -93,13 +93,9 @@ kernel void dustEffectUpdateParticle(
float particleXFraction = float(particleX) / float(size.x);
float particleFraction = particleEaseInValueAt(effectFraction, particleXFraction);
//Loki rng = Loki(gid, uint(phase * timeStep));
//float2 offsetNorm = float2(1.0, 1.0) * 10.0 * timeStep;
Particle particle = particles[gid];
particle.offsetFromBasePosition += (particle.velocity * timeStep) * particleFraction;
//particle.velocity += ((-offsetNorm) * 0.5 + float2(rng.rand(), rng.rand()) * offsetNorm) * particleFraction;
//particle.velocity = particle.velocity * (1.0 - particleFraction) + particle.velocity * 1.001 * particleFraction;
particle.velocity += float2(0.0, timeStep * 120.0) * particleFraction;
particle.lifetime = max(0.0, particle.lifetime - timeStep * particleFraction);
particles[gid] = particle;

View File

@ -162,7 +162,6 @@ public final class DustEffectLayer: MetalEngineSubjectLayer, MetalEngineSubject
}
self.lastTimeStep = deltaTimeValue
//print("updateItems: \(deltaTime), localDeltaTime: \(localDeltaTime)")
var didRemoveItems = false
for i in (0 ..< self.items.count).reversed() {
@ -224,19 +223,6 @@ public final class DustEffectLayer: MetalEngineSubjectLayer, MetalEngineSubject
if item.particleBuffer == nil {
if let particleBuffer = MetalEngine.shared.sharedBuffer(spec: BufferSpec(length: particleCount * 4 * (4 + 1))) {
item.particleBuffer = particleBuffer
/*let particles = particleBuffer.buffer.contents().assumingMemoryBound(to: Float.self)
for i in 0 ..< particleCount {
particles[i * 5 + 0] = 0.0;
particles[i * 5 + 1] = 0.0;
let direction = Float.random(in: 0.0 ..< Float.pi * 2.0)
let velocity = Float.random(in: 0.1 ... 0.2) * 420.0
particles[i * 5 + 2] = cos(direction) * velocity
particles[i * 5 + 3] = sin(direction) * velocity
particles[i * 5 + 4] = Float.random(in: 0.7 ... 1.5)
}*/
}
}
}
@ -279,6 +265,7 @@ public final class DustEffectLayer: MetalEngineSubjectLayer, MetalEngineSubject
var phase = item.phase
computeEncoder.setBytes(&phase, length: 4, index: 2)
var timeStep: Float = Float(lastTimeStep) / Float(UIView.animationDurationFactor())
timeStep *= 2.0
computeEncoder.setBytes(&timeStep, length: 4, index: 3)
computeEncoder.dispatchThreadgroups(threadgroupCount, threadsPerThreadgroup: threadgroupSize)
}

View File

@ -3127,9 +3127,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { [weak self] controller, f in
if let strongSelf = self {
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds([id])
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: [id], type: .forLocalPeer).startStandalone()
}
f(.dismissWithoutContent)
@ -8747,15 +8744,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
if isAction && (actions.options == .deleteGlobally || actions.options == .deleteLocally) {
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: actions.options == .deleteLocally ? .forLocalPeer : .forEveryone).startStandalone()
completion(.dismissWithoutContent)
} else if (messages.first?.flags.isSending ?? false) {
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).startStandalone()
completion(.dismissWithoutContent)
} else {
@ -17218,9 +17209,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let _ = strongSelf.context.engine.messages.deleteAllMessagesWithAuthor(peerId: peerId, authorId: author.id, namespace: Namespaces.Message.Cloud).startStandalone()
let _ = strongSelf.context.engine.messages.clearAuthorHistory(peerId: peerId, memberId: author.id).startStandalone()
} else if actions.contains(0) {
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
}
if actions.contains(1) {
@ -17259,9 +17247,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
}
}))
@ -17286,7 +17271,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
globalTitle = self.presentationData.strings.Conversation_DeleteMessagesForEveryone
}
contextItems.append(.action(ContextMenuActionItem(text: globalTitle, textColor: .destructive, icon: { _ in nil }, action: { [weak self] _, f in
contextItems.append(.action(ContextMenuActionItem(text: globalTitle, textColor: .destructive, icon: { _ in nil }, action: { [weak self] c, f in
if let strongSelf = self {
var giveaway: TelegramMediaGiveaway?
for messageId in messageIds {
@ -17299,9 +17284,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let commit = {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
}
if let giveaway {
@ -17314,8 +17296,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
f(.default)
} else {
commit()
f(.dismissWithoutContent)
c.dismiss(completion: {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: {
commit()
})
})
}
}
})))
@ -17323,9 +17308,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: .forEveryone).startStandalone()
}
}))
@ -17349,29 +17331,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
c.dismiss(completion: { [weak strongSelf] in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: {
guard let strongSelf else {
return
}
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone()
})
c.dismiss(completion: { [weak strongSelf] in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: {
guard let strongSelf else {
return
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone()
})
} else {
f(.dismissWithoutContent)
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone()
}
})
}
})))
items.append(ActionSheetButtonItem(title: localOptionText, color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
if strongSelf.context.sharedContext.immediateExperimentalUISettings.dustEffect {
strongSelf.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(messageIds)
}
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).startStandalone()
}

View File

@ -29,6 +29,7 @@ import ChatBotInfoItem
import ChatMessageItem
import ChatMessageItemImpl
import ChatMessageItemView
import ChatMessageBubbleItemNode
import ChatMessageTransitionNode
import ChatControllerInteraction
import DustEffect
@ -677,6 +678,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
private var toLang: String?
private var allowDustEffect: Bool = true
private var dustEffectLayer: DustEffectLayer?
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?) {
@ -694,8 +696,13 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
self.controllerInteraction = controllerInteraction
self.mode = mode
if let data = context.currentAppConfiguration.with({ $0 }).data, let _ = data["ios_killswitch_disable_unread_alignment"] {
self.enableUnreadAlignment = false
if let data = context.currentAppConfiguration.with({ $0 }).data {
if let _ = data["ios_killswitch_disable_unread_alignment"] {
self.enableUnreadAlignment = false
}
if let _ = data["ios_killswitch_disable_dust_effect"] {
self.allowDustEffect = false
}
}
let presentationData = updatedPresentationData.initial
@ -2957,22 +2964,16 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
self.hasActiveTransition = true
let transition = self.enqueuedHistoryViewTransitions.removeFirst()
var expiredMessageIds = Set<MessageId>()
var expiredMessageStableIds = Set<UInt32>()
if let previousHistoryView = self.historyView, transition.options.contains(.AnimateInsertion) {
let demoDustEffect = self.context.sharedContext.immediateExperimentalUISettings.dustEffect
var existingIds = Set<MessageId>()
var existingStableIds = Set<UInt32>()
for entry in transition.historyView.filteredEntries {
switch entry {
case let .MessageEntry(message, _, _, _, _, _):
if message.autoremoveAttribute != nil || demoDustEffect {
existingIds.insert(message.id)
}
existingStableIds.insert(message.stableId)
case let .MessageGroupEntry(_, messages, _):
for message in messages {
if message.0.autoremoveAttribute != nil || demoDustEffect {
existingIds.insert(message.0.id)
}
existingStableIds.insert(message.0.stableId)
}
default:
break
@ -2982,25 +2983,25 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
for entry in previousHistoryView.filteredEntries {
switch entry {
case let .MessageEntry(message, _, _, _, _, _):
if !existingIds.contains(message.id) {
if !existingStableIds.contains(message.stableId) {
if let autoremoveAttribute = message.autoremoveAttribute, let countdownBeginTime = autoremoveAttribute.countdownBeginTime {
let exipiresAt = countdownBeginTime + autoremoveAttribute.timeout
if exipiresAt >= currentTimestamp - 1 {
expiredMessageIds.insert(message.id)
expiredMessageStableIds.insert(message.stableId)
}
} else if demoDustEffect {
expiredMessageIds.insert(message.id)
} else {
expiredMessageStableIds.insert(message.stableId)
}
}
case let .MessageGroupEntry(_, messages, _):
for message in messages {
if !existingIds.contains(message.0.id) {
if !existingStableIds.contains(message.0.stableId) {
if let autoremoveAttribute = message.0.autoremoveAttribute, let countdownBeginTime = autoremoveAttribute.countdownBeginTime {
let exipiresAt = countdownBeginTime + autoremoveAttribute.timeout
if exipiresAt >= currentTimestamp - 1 {
expiredMessageIds.insert(message.0.id)
} else if demoDustEffect {
expiredMessageIds.insert(message.0.id)
expiredMessageStableIds.insert(message.0.stableId)
} else {
expiredMessageStableIds.insert(message.0.stableId)
}
}
}
@ -3010,17 +3011,23 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
}
}
self.currentDeleteAnimationCorrelationIds.formUnion(expiredMessageIds)
self.currentDeleteAnimationCorrelationIds.formUnion(expiredMessageStableIds)
var appliedDeleteAnimationCorrelationIds = Set<MessageId>()
if !self.currentDeleteAnimationCorrelationIds.isEmpty {
var appliedDeleteAnimationCorrelationIds = Set<UInt32>()
if !self.currentDeleteAnimationCorrelationIds.isEmpty && self.allowDustEffect {
var foundItemNodes: [ChatMessageItemView] = []
self.forEachItemNode { itemNode in
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
for (message, _) in item.content {
if self.currentDeleteAnimationCorrelationIds.contains(message.id) {
appliedDeleteAnimationCorrelationIds.insert(message.id)
self.currentDeleteAnimationCorrelationIds.remove(message.id)
if let itemNode = itemNode as? ChatMessageBubbleItemNode {
if itemNode.isServiceLikeMessage() {
continue
}
}
if self.currentDeleteAnimationCorrelationIds.contains(message.stableId) {
appliedDeleteAnimationCorrelationIds.insert(message.stableId)
self.currentDeleteAnimationCorrelationIds.remove(message.stableId)
foundItemNodes.append(itemNode)
}
}
@ -4051,11 +4058,11 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
self.currentSendAnimationCorrelationIds = value
}
private var currentDeleteAnimationCorrelationIds = Set<MessageId>()
func setCurrentDeleteAnimationCorrelationIds(_ value: Set<MessageId>) {
private var currentDeleteAnimationCorrelationIds = Set<UInt32>()
func setCurrentDeleteAnimationCorrelationIds(_ value: Set<UInt32>) {
self.currentDeleteAnimationCorrelationIds = value
}
private var currentAppliedDeleteAnimationCorrelationIds = Set<MessageId>()
private var currentAppliedDeleteAnimationCorrelationIds = Set<UInt32>()
var animationCorrelationMessagesFound: (([Int64: ChatMessageItemView]) -> Void)?
@ -4155,8 +4162,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
if !self.currentAppliedDeleteAnimationCorrelationIds.isEmpty {
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
for (message, _) in item.content {
if self.currentAppliedDeleteAnimationCorrelationIds.contains(message.id) {
return 1.5
if self.currentAppliedDeleteAnimationCorrelationIds.contains(message.stableId) {
return 0.8
}
}
}