Various improvements

This commit is contained in:
Ilya Laktyushin 2026-04-29 18:22:42 +02:00
parent 37d1e2d93e
commit 06a0031bdd
3 changed files with 90 additions and 5 deletions

View file

@ -76,9 +76,93 @@ func _internal_deleteAllMessagesWithForwardAuthor(transaction: Transaction, medi
}
}
func _internal_deleteAllReactionsWithAuthor(account: Account, peerId: PeerId, authorId: PeerId) -> Signal<Never, NoError> {
func _internal_deleteAllReactionsWithAuthor(account: Account, peerId: PeerId, authorId: PeerId, aroundMessageId: MessageId?) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> (Peer?, Peer?) in
return (transaction.getPeer(peerId), transaction.getPeer(authorId))
let peer = transaction.getPeer(peerId)
let author = transaction.getPeer(authorId)
if peer.flatMap(apiInputPeer) != nil && author.flatMap(apiInputPeer) != nil {
let anchor: HistoryViewInputAnchor
if let aroundMessageId, aroundMessageId.peerId == peerId {
anchor = .message(aroundMessageId)
} else {
anchor = .upperBound
}
let historyView = transaction.getMessagesHistoryViewState(input: .single(peerId: peerId, threadId: nil), ignoreMessagesInTimestampRange: nil, ignoreMessageIds: Set(), count: 50, clipHoles: true, anchor: anchor, namespaces: .just(Set([Namespaces.Message.Cloud])))
for entry in historyView.entries {
transaction.updateMessage(entry.message.id, update: { currentMessage in
var attributes = currentMessage.attributes
var updated = false
for i in 0 ..< attributes.count {
guard let attribute = attributes[i] as? ReactionsMessageAttribute else {
continue
}
let removedRecentPeers = attribute.recentPeers.filter { $0.peerId == authorId }
var updatedTopPeers = attribute.topPeers
var removedStarsTopPeerCount: Int32 = 0
for j in (0 ..< updatedTopPeers.count).reversed() {
if updatedTopPeers[j].peerId == authorId {
removedStarsTopPeerCount += updatedTopPeers[j].count
updatedTopPeers.remove(at: j)
}
}
if removedRecentPeers.isEmpty && removedStarsTopPeerCount == 0 {
continue
}
var updatedReactions = attribute.reactions
for removedRecentPeer in removedRecentPeers {
if let index = updatedReactions.firstIndex(where: { $0.value == removedRecentPeer.value }) {
if removedRecentPeer.value != .stars || removedStarsTopPeerCount == 0 {
updatedReactions[index].count -= 1
}
if removedRecentPeer.isMy {
updatedReactions[index].chosenOrder = nil
}
}
}
if removedStarsTopPeerCount != 0, let index = updatedReactions.firstIndex(where: { $0.value == .stars }) {
updatedReactions[index].count -= removedStarsTopPeerCount
}
for j in (0 ..< updatedReactions.count).reversed() {
if updatedReactions[j].count <= 0 {
updatedReactions.remove(at: j)
}
}
let updatedRecentPeers = attribute.recentPeers.filter { $0.peerId != authorId }
let updatedAttribute = ReactionsMessageAttribute(canViewList: attribute.canViewList, isTags: attribute.isTags, reactions: updatedReactions, recentPeers: updatedRecentPeers, topPeers: updatedTopPeers)
if updatedAttribute != attribute {
attributes[i] = updatedAttribute
updated = true
}
}
if !updated {
return .skip
}
var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author?.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature, psaType: forwardInfo.psaType, flags: forwardInfo.flags)
}
var tags = currentMessage.tags
if attributes.contains(where: { ($0 as? ReactionsMessageAttribute)?.hasUnseen == true }) {
tags.insert(.unseenReaction)
} else {
tags.remove(.unseenReaction)
}
return .update(StoreMessage(id: currentMessage.id, customStableId: nil, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
}
}
return (peer, author)
}
|> mapToSignal { peer, author in
guard let inputPeer = peer.flatMap(apiInputPeer), let inputAuthor = author.flatMap(apiInputPeer) else {

View file

@ -170,8 +170,8 @@ public extension TelegramEngine {
|> ignoreValues
}
public func deleteAllReactionsWithAuthor(peerId: EnginePeer.Id, authorId: EnginePeer.Id) -> Signal<Never, NoError> {
return _internal_deleteAllReactionsWithAuthor(account: self.account, peerId: peerId, authorId: authorId)
public func deleteAllReactionsWithAuthor(peerId: EnginePeer.Id, authorId: EnginePeer.Id, aroundMessageId: EngineMessage.Id? = nil) -> Signal<Never, NoError> {
return _internal_deleteAllReactionsWithAuthor(account: self.account, peerId: peerId, authorId: authorId, aroundMessageId: aroundMessageId)
}
public func deleteReaction(messageId: EngineMessage.Id, authorId: EnginePeer.Id) -> Signal<Never, NoError> {

View file

@ -85,8 +85,9 @@ extension ChatControllerImpl {
let _ = self.context.engine.messages.clearAuthorHistory(peerId: messagesPeerId, memberId: authorId).startStandalone()
}
let aroundMessageId = messageIds.count == 1 ? messageIds.first : nil
for authorId in result.deleteAllReactionsFromPeers {
let _ = self.context.engine.messages.deleteAllReactionsWithAuthor(peerId: messagesPeerId, authorId: authorId).startStandalone()
let _ = self.context.engine.messages.deleteAllReactionsWithAuthor(peerId: messagesPeerId, authorId: authorId, aroundMessageId: aroundMessageId).startStandalone()
}
for authorId in result.reportSpamPeers {