mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
165 lines
6.6 KiB
Swift
165 lines
6.6 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import TelegramApi
|
|
|
|
extension ReactionsMessageAttribute {
|
|
func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
|
|
switch reactions {
|
|
case let .messageReactions(flags, results, recentReactions):
|
|
let min = (flags & (1 << 0)) != 0
|
|
let canViewList = (flags & (1 << 2)) != 0
|
|
var reactions = results.map { result -> MessageReaction in
|
|
switch result {
|
|
case let .reactionCount(flags, reaction, count):
|
|
return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0)
|
|
}
|
|
}
|
|
let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer]
|
|
if let recentReactions = recentReactions {
|
|
parsedRecentReactions = recentReactions.map { recentReaction -> ReactionsMessageAttribute.RecentPeer in
|
|
switch recentReaction {
|
|
case let .messagePeerReaction(flags, peerId, reaction):
|
|
let isLarge = (flags & (1 << 0)) != 0
|
|
let isUnseen = (flags & (1 << 1)) != 0
|
|
return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId)
|
|
}
|
|
}
|
|
} else {
|
|
parsedRecentReactions = []
|
|
}
|
|
|
|
if min {
|
|
var currentSelectedReaction: String?
|
|
for reaction in self.reactions {
|
|
if reaction.isSelected {
|
|
currentSelectedReaction = reaction.value
|
|
break
|
|
}
|
|
}
|
|
if let currentSelectedReaction = currentSelectedReaction {
|
|
for i in 0 ..< reactions.count {
|
|
if reactions[i].value == currentSelectedReaction {
|
|
reactions[i].isSelected = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ReactionsMessageAttribute(canViewList: canViewList, reactions: reactions, recentPeers: parsedRecentReactions)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func mergedMessageReactionsAndPeers(message: Message) -> (reactions: [MessageReaction], peers: [(String, EnginePeer)]) {
|
|
guard let attribute = mergedMessageReactions(attributes: message.attributes) else {
|
|
return ([], [])
|
|
}
|
|
|
|
var recentPeers = attribute.recentPeers.compactMap { recentPeer -> (String, EnginePeer)? in
|
|
if let peer = message.peers[recentPeer.peerId] {
|
|
return (recentPeer.value, EnginePeer(peer))
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
|
|
recentPeers.removeAll()
|
|
}
|
|
|
|
return (attribute.reactions, recentPeers)
|
|
}
|
|
|
|
public func mergedMessageReactions(attributes: [MessageAttribute]) -> ReactionsMessageAttribute? {
|
|
var current: ReactionsMessageAttribute?
|
|
var pending: PendingReactionsMessageAttribute?
|
|
for attribute in attributes {
|
|
if let attribute = attribute as? ReactionsMessageAttribute {
|
|
current = attribute
|
|
} else if let attribute = attribute as? PendingReactionsMessageAttribute {
|
|
pending = attribute
|
|
}
|
|
}
|
|
|
|
if let pending = pending {
|
|
var reactions = current?.reactions ?? []
|
|
var recentPeers = current?.recentPeers ?? []
|
|
if let value = pending.value {
|
|
var found = false
|
|
for i in 0 ..< reactions.count {
|
|
if reactions[i].value == value {
|
|
found = true
|
|
if !reactions[i].isSelected {
|
|
reactions[i].isSelected = true
|
|
reactions[i].count += 1
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
reactions.append(MessageReaction(value: value, count: 1, isSelected: true))
|
|
}
|
|
}
|
|
if let accountPeerId = pending.accountPeerId {
|
|
for i in 0 ..< recentPeers.count {
|
|
if recentPeers[i].peerId == accountPeerId {
|
|
recentPeers.remove(at: i)
|
|
break
|
|
}
|
|
}
|
|
if let value = pending.value {
|
|
recentPeers.append(ReactionsMessageAttribute.RecentPeer(value: value, isLarge: false, isUnseen: false, peerId: accountPeerId))
|
|
}
|
|
}
|
|
for i in (0 ..< reactions.count).reversed() {
|
|
if reactions[i].isSelected, pending.value != reactions[i].value {
|
|
if reactions[i].count == 1 {
|
|
reactions.remove(at: i)
|
|
} else {
|
|
reactions[i].isSelected = false
|
|
reactions[i].count -= 1
|
|
}
|
|
}
|
|
}
|
|
if !reactions.isEmpty {
|
|
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, reactions: reactions, recentPeers: recentPeers)
|
|
} else {
|
|
return nil
|
|
}
|
|
} else if let current = current {
|
|
return current
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
extension ReactionsMessageAttribute {
|
|
convenience init(apiReactions: Api.MessageReactions) {
|
|
switch apiReactions {
|
|
case let .messageReactions(flags, results, recentReactions):
|
|
let canViewList = (flags & (1 << 2)) != 0
|
|
let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer]
|
|
if let recentReactions = recentReactions {
|
|
parsedRecentReactions = recentReactions.map { recentReaction -> ReactionsMessageAttribute.RecentPeer in
|
|
switch recentReaction {
|
|
case let .messagePeerReaction(flags, peerId, reaction):
|
|
let isLarge = (flags & (1 << 0)) != 0
|
|
let isUnseen = (flags & (1 << 1)) != 0
|
|
return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId)
|
|
}
|
|
}
|
|
} else {
|
|
parsedRecentReactions = []
|
|
}
|
|
|
|
self.init(
|
|
canViewList: canViewList,
|
|
reactions: results.map { result in
|
|
switch result {
|
|
case let .reactionCount(flags, reaction, count):
|
|
return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0)
|
|
}
|
|
},
|
|
recentPeers: parsedRecentReactions
|
|
)
|
|
}
|
|
}
|
|
}
|