Update API

This commit is contained in:
Ali 2022-08-21 18:39:51 +03:00
parent ffe00ac2e1
commit 31d56bc12e
14 changed files with 360 additions and 130 deletions

View File

@ -1156,6 +1156,11 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
let animateAppearingContainers = transition.isAnimated && !self.dismissingItemContainers.isEmpty
struct TipLayout {
var tipNode: ASDisplayNode
var tipHeight: CGFloat
}
struct ItemLayout {
var size: CGSize
var apparentHeight: CGFloat
@ -1163,6 +1168,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
var alphaTransitionFraction: CGFloat
var itemTransition: ContainedViewLayoutTransition
var animateAppearingContainer: Bool
var tip: TipLayout?
}
var topItemSize = CGSize()
@ -1204,13 +1210,19 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
topItemSize = itemSize.size
}
var tip: TipLayout?
if let (tipNode, tipHeight) = itemContainer.updateTip(presentationData: presentationData, width: itemSize.size.width, transition: itemContainerTransition) {
tip = TipLayout(tipNode: tipNode, tipHeight: tipHeight)
}
itemLayouts.append(ItemLayout(
size: itemSize.size,
apparentHeight: itemSize.apparentHeight,
transitionFraction: transitionFraction,
alphaTransitionFraction: alphaTransitionFraction,
itemTransition: itemContainerTransition,
animateAppearingContainer: animateAppearingContainer
animateAppearingContainer: animateAppearingContainer,
tip: tip
))
}
@ -1232,6 +1244,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
}
let navigationContainerFrame = CGRect(origin: CGPoint(), size: CGSize(width: topItemWidth, height: max(14 * 2.0, topItemApparentHeight)))
let previousNavigationContainerFrame = self.navigationContainer.frame
transition.updateFrame(node: self.navigationContainer, frame: navigationContainerFrame, beginWithCurrentState: true)
self.navigationContainer.update(presentationData: presentationData, presentation: presentation, size: navigationContainerFrame.size, transition: transition)
@ -1258,20 +1271,28 @@ final class ContextControllerActionsStackNode: ASDisplayNode {
self.itemContainers[i].updateDimNode(presentationData: presentationData, size: CGSize(width: itemLayouts[i].size.width, height: navigationContainerFrame.size.height), transitionFraction: itemLayouts[i].alphaTransitionFraction, transition: transition)
if let (tipNode, tipHeight) = self.itemContainers[i].updateTip(presentationData: presentationData, width: itemLayouts[i].size.width, transition: transition) {
var tipTransition = transition
if tipNode.supernode == nil {
tipTransition = .immediate
self.addSubnode(tipNode)
if let tip = itemLayouts[i].tip {
let tipTransition = transition
var animateTipIn = false
if tip.tipNode.supernode == nil {
self.addSubnode(tip.tipNode)
animateTipIn = transition.isAnimated
tip.tipNode.frame = CGRect(origin: CGPoint(x: previousNavigationContainerFrame.minX, y: previousNavigationContainerFrame.maxY + tipSpacing), size: CGSize(width: itemLayouts[i].size.width, height: tip.tipHeight))
}
let tipAlpha: CGFloat = itemLayouts[i].alphaTransitionFraction
tipTransition.updateFrame(node: tipNode, frame: CGRect(origin: CGPoint(x: navigationContainerFrame.minX, y: navigationContainerFrame.maxY + tipSpacing), size: CGSize(width: itemLayouts[i].size.width, height: tipHeight)), beginWithCurrentState: true)
tipTransition.updateAlpha(node: tipNode, alpha: tipAlpha, beginWithCurrentState: true)
tipTransition.updateFrame(node: tip.tipNode, frame: CGRect(origin: CGPoint(x: navigationContainerFrame.minX, y: navigationContainerFrame.maxY + tipSpacing), size: CGSize(width: itemLayouts[i].size.width, height: tip.tipHeight)), beginWithCurrentState: true)
if animateTipIn {
tip.tipNode.alpha = tipAlpha
tip.tipNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
} else {
tipTransition.updateAlpha(node: tip.tipNode, alpha: tipAlpha, beginWithCurrentState: true)
}
if i == self.itemContainers.count - 1 {
topItemSize.height += tipSpacing + tipHeight
topItemSize.height += tipSpacing + tip.tipHeight
}
}
}

View File

@ -323,24 +323,22 @@ public func peerAllowedReactionListController(
updateState { state in
var state = state
if allowedReactions == nil {
switch allowedReactions {
case .unknown:
break
case let .known(value):
switch value {
case .all:
state.updatedMode = .all
if let availableReactions = availableReactions {
let updatedAllowedReactions = availableReactions.reactions.map { $0.value }
state.updatedAllowedReactions = Set(updatedAllowedReactions)
}
} else if let allowedReactions = allowedReactions, !allowedReactions.isEmpty {
if let availableReactions = availableReactions, Set(allowedReactions) == Set(availableReactions.reactions.map(\.value)) {
state.updatedMode = .all
} else {
state.updatedAllowedReactions = Set()
case let .limited(reactions):
state.updatedMode = .some
}
let updatedAllowedReactions = Set(allowedReactions)
state.updatedAllowedReactions = updatedAllowedReactions
} else {
state.updatedAllowedReactions = Set(reactions)
case .empty:
state.updatedMode = .empty
state.updatedAllowedReactions = Set()
}
}
return state
}
@ -371,6 +369,12 @@ public func peerAllowedReactionListController(
}
case .some:
updatedAllowedReactions.removeAll()
if let thumbsUp = availableReactions.reactions.first(where: { $0.value == .builtin("👍") }) {
updatedAllowedReactions.insert(thumbsUp.value)
}
if let thumbsDown = availableReactions.reactions.first(where: { $0.value == .builtin("👎") }) {
updatedAllowedReactions.insert(thumbsDown.value)
}
case .empty:
updatedAllowedReactions.removeAll()
}
@ -443,12 +447,24 @@ public func peerAllowedReactionListController(
let controller = ItemListController(context: context, state: signal)
controller.willDisappear = { _ in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.AllowedReactions(id: peerId))
|> deliverOnMainQueue).start(next: { initialAllowedReactionList in
let initialAllowedReactions = initialAllowedReactionList.flatMap(Set.init)
|> deliverOnMainQueue).start(next: { initialAllowedReactions in
let state = stateValue.with({ $0 })
guard let updatedMode = state.updatedMode, let updatedAllowedReactions = state.updatedAllowedReactions else {
return
}
let updatedAllowedReactions = stateValue.with({ $0 }).updatedAllowedReactions
if let updatedAllowedReactions = updatedAllowedReactions, initialAllowedReactions != updatedAllowedReactions {
let _ = context.engine.peers.updatePeerAllowedReactions(peerId: peerId, allowedReactions: Array(updatedAllowedReactions)).start()
let updatedValue: PeerAllowedReactions
switch updatedMode {
case .all:
updatedValue = .all
case .some:
updatedValue = .limited(Array(updatedAllowedReactions))
case .empty:
updatedValue = .empty
}
if initialAllowedReactions != .known(updatedValue) {
let _ = context.engine.peers.updatePeerAllowedReactions(peerId: peerId, allowedReactions: updatedValue).start()
}
})
}

View File

@ -151,8 +151,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1605510357] = { return Api.ChatAdminRights.parse_chatAdminRights($0) }
dict[-219353309] = { return Api.ChatAdminWithInvites.parse_chatAdminWithInvites($0) }
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
dict[-362240487] = { return Api.ChatFull.parse_channelFull($0) }
dict[-779165146] = { return Api.ChatFull.parse_chatFull($0) }
dict[-231385849] = { return Api.ChatFull.parse_channelFull($0) }
dict[-908914376] = { return Api.ChatFull.parse_chatFull($0) }
dict[806110401] = { return Api.ChatInvite.parse_chatInvite($0) }
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
@ -165,6 +165,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-2023500831] = { return Api.ChatParticipants.parse_chatParticipantsForbidden($0) }
dict[476978193] = { return Api.ChatPhoto.parse_chatPhoto($0) }
dict[935395612] = { return Api.ChatPhoto.parse_chatPhotoEmpty($0) }
dict[1385335754] = { return Api.ChatReactions.parse_chatReactionsAll($0) }
dict[-352570692] = { return Api.ChatReactions.parse_chatReactionsNone($0) }
dict[1713193015] = { return Api.ChatReactions.parse_chatReactionsSome($0) }
dict[-1973130814] = { return Api.CodeSettings.parse_codeSettings($0) }
dict[589653676] = { return Api.Config.parse_config($0) }
dict[341499403] = { return Api.Contact.parse_contact($0) }
@ -1207,6 +1210,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.ChatPhoto:
_1.serialize(buffer, boxed)
case let _1 as Api.ChatReactions:
_1.serialize(buffer, boxed)
case let _1 as Api.CodeSettings:
_1.serialize(buffer, boxed)
case let _1 as Api.Config:

View File

@ -5321,6 +5321,23 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func reportReaction(peer: Api.InputPeer, id: Int32, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1631726152)
peer.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
userId.serialize(buffer, true)
return (FunctionDescription(name: "messages.reportReaction", parameters: [("peer", String(describing: peer)), ("id", String(describing: id)), ("userId", String(describing: userId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.messages {
static func reportSpam(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -5898,15 +5915,11 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func setChatAvailableReactions(peer: Api.InputPeer, availableReactions: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func setChatAvailableReactions(peer: Api.InputPeer, availableReactions: Api.ChatReactions) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(335875750)
buffer.appendInt32(-21928079)
peer.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(availableReactions.count))
for item in availableReactions {
serializeString(item, buffer: buffer, boxed: false)
}
availableReactions.serialize(buffer, true)
return (FunctionDescription(name: "messages.setChatAvailableReactions", parameters: [("peer", String(describing: peer)), ("availableReactions", String(describing: availableReactions))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?

View File

@ -880,14 +880,14 @@ public extension Api {
}
public extension Api {
enum ChatFull: TypeConstructorDescription {
case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: [String]?)
case chatFull(flags: Int32, id: Int64, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttlPeriod: Int32?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, availableReactions: [String]?)
case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?)
case chatFull(flags: Int32, id: Int64, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttlPeriod: Int32?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, availableReactions: Api.ChatReactions?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions):
if boxed {
buffer.appendInt32(-362240487)
buffer.appendInt32(-231385849)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(flags2, buffer: buffer, boxed: false)
@ -937,15 +937,11 @@ public extension Api {
serializeInt64(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 29) != 0 {defaultSendAs!.serialize(buffer, true)}
if Int(flags) & Int(1 << 30) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(availableReactions!.count))
for item in availableReactions! {
serializeString(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 30) != 0 {availableReactions!.serialize(buffer, true)}
break
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions):
if boxed {
buffer.appendInt32(-779165146)
buffer.appendInt32(-908914376)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
@ -971,11 +967,7 @@ public extension Api {
for item in recentRequesters! {
serializeInt64(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 18) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(availableReactions!.count))
for item in availableReactions! {
serializeString(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 18) != 0 {availableReactions!.serialize(buffer, true)}
break
}
}
@ -1084,9 +1076,9 @@ public extension Api {
if Int(_1!) & Int(1 << 29) != 0 {if let signature = reader.readInt32() {
_36 = Api.parse(reader, signature: signature) as? Api.Peer
} }
var _37: [String]?
if Int(_1!) & Int(1 << 30) != 0 {if let _ = reader.readInt32() {
_37 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
var _37: Api.ChatReactions?
if Int(_1!) & Int(1 << 30) != 0 {if let signature = reader.readInt32() {
_37 = Api.parse(reader, signature: signature) as? Api.ChatReactions
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
@ -1181,9 +1173,9 @@ public extension Api {
if Int(_1!) & Int(1 << 17) != 0 {if let _ = reader.readInt32() {
_16 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
} }
var _17: [String]?
if Int(_1!) & Int(1 << 18) != 0 {if let _ = reader.readInt32() {
_17 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
var _17: Api.ChatReactions?
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
_17 = Api.parse(reader, signature: signature) as? Api.ChatReactions
} }
let _c1 = _1 != nil
let _c2 = _2 != nil

View File

@ -318,6 +318,80 @@ public extension Api {
}
}
public extension Api {
enum ChatReactions: TypeConstructorDescription {
case chatReactionsAll(flags: Int32)
case chatReactionsNone
case chatReactionsSome(reactions: [Api.Reaction])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .chatReactionsAll(let flags):
if boxed {
buffer.appendInt32(1385335754)
}
serializeInt32(flags, buffer: buffer, boxed: false)
break
case .chatReactionsNone:
if boxed {
buffer.appendInt32(-352570692)
}
break
case .chatReactionsSome(let reactions):
if boxed {
buffer.appendInt32(1713193015)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(reactions.count))
for item in reactions {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .chatReactionsAll(let flags):
return ("chatReactionsAll", [("flags", String(describing: flags))])
case .chatReactionsNone:
return ("chatReactionsNone", [])
case .chatReactionsSome(let reactions):
return ("chatReactionsSome", [("reactions", String(describing: reactions))])
}
}
public static func parse_chatReactionsAll(_ reader: BufferReader) -> ChatReactions? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.ChatReactions.chatReactionsAll(flags: _1!)
}
else {
return nil
}
}
public static func parse_chatReactionsNone(_ reader: BufferReader) -> ChatReactions? {
return Api.ChatReactions.chatReactionsNone
}
public static func parse_chatReactionsSome(_ reader: BufferReader) -> ChatReactions? {
var _1: [Api.Reaction]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Reaction.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.ChatReactions.chatReactionsSome(reactions: _1!)
}
else {
return nil
}
}
}
}
public extension Api {
enum CodeSettings: TypeConstructorDescription {
case codeSettings(flags: Int32, logoutTokens: [Buffer]?)

View File

@ -558,7 +558,7 @@ public enum UpdatePeerAllowedReactionsError {
case generic
}
func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allowedReactions: [MessageReaction.Reaction]) -> Signal<Never, UpdatePeerAllowedReactionsError> {
func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allowedReactions: PeerAllowedReactions) -> Signal<Never, UpdatePeerAllowedReactionsError> {
return account.postbox.transaction { transaction -> Api.InputPeer? in
return transaction.getPeer(peerId).flatMap(apiInputPeer)
}
@ -567,14 +567,18 @@ func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allo
guard let inputPeer = inputPeer else {
return .fail(.generic)
}
return account.network.request(Api.functions.messages.setChatAvailableReactions(peer: inputPeer, availableReactions: allowedReactions.compactMap { item -> String? in
switch item {
case let .builtin(value):
return value
case .custom:
return nil
let mappedReactions: Api.ChatReactions
switch allowedReactions {
case .all:
mappedReactions = .chatReactionsAll(flags: 0)
case let .limited(array):
mappedReactions = .chatReactionsSome(reactions: array.map(\.apiReaction))
case .empty:
mappedReactions = .chatReactionsNone
}
}))
return account.network.request(Api.functions.messages.setChatAvailableReactions(peer: inputPeer, availableReactions: mappedReactions))
|> mapError { _ -> UpdatePeerAllowedReactionsError in
return .generic
}
@ -584,9 +588,9 @@ func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allo
return account.postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
if let current = current as? CachedChannelData {
return current.withUpdatedAllowedReactions(allowedReactions)
return current.withUpdatedAllowedReactions(.known(allowedReactions))
} else if let current = current as? CachedGroupData {
return current.withUpdatedAllowedReactions(allowedReactions)
return current.withUpdatedAllowedReactions(.known(allowedReactions))
} else {
return current
}

View File

@ -238,7 +238,7 @@ public final class CachedChannelData: CachedPeerData {
public let themeEmoticon: String?
public let inviteRequestsPending: Int32?
public let sendAsPeerId: PeerId?
public let allowedReactions: [MessageReaction.Reaction]?
public let allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>
public let peerIds: Set<PeerId>
public let messageIds: Set<MessageId>
@ -276,7 +276,7 @@ public final class CachedChannelData: CachedPeerData {
self.themeEmoticon = nil
self.inviteRequestsPending = nil
self.sendAsPeerId = nil
self.allowedReactions = nil
self.allowedReactions = .unknown
}
public init(
@ -307,7 +307,7 @@ public final class CachedChannelData: CachedPeerData {
themeEmoticon: String?,
inviteRequestsPending: Int32?,
sendAsPeerId: PeerId?,
allowedReactions: [MessageReaction.Reaction]?
allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>
) {
self.isNotAccessible = isNotAccessible
self.flags = flags
@ -471,7 +471,7 @@ public final class CachedChannelData: CachedPeerData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, allowedReactions: self.allowedReactions)
}
public func withUpdatedAllowedReactions(_ allowedReactions: [MessageReaction.Reaction]?) -> CachedChannelData {
public func withUpdatedAllowedReactions(_ allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: allowedReactions)
}
@ -562,10 +562,12 @@ public final class CachedChannelData: CachedPeerData {
self.sendAsPeerId = decoder.decodeOptionalInt64ForKey("sendAsPeerId").flatMap(PeerId.init)
if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin)
if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = .known(.limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin)))
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
self.allowedReactions = .known(allowedReactions)
} else {
self.allowedReactions = nil
self.allowedReactions = .unknown
}
if case let .known(linkedDiscussionPeerIdValue) = self.linkedDiscussionPeerId {
@ -712,17 +714,11 @@ public final class CachedChannelData: CachedPeerData {
encoder.encodeNil(forKey: "sendAsPeerId")
}
if let allowedReactions = self.allowedReactions {
encoder.encodeStringArray(allowedReactions.compactMap { item -> String? in
switch item {
case let .builtin(value):
return value
case .custom:
return nil
}
}, forKey: "allowedReactions")
} else {
encoder.encodeNil(forKey: "allowedReactions")
switch self.allowedReactions {
case .unknown:
encoder.encodeNil(forKey: "allowedReactionSet")
case let .known(value):
encoder.encode(value, forKey: "allowedReactionSet")
}
}

View File

@ -39,6 +39,49 @@ public struct CachedGroupFlags: OptionSet {
public static let canChangeUsername = CachedGroupFlags(rawValue: 1 << 0)
}
public enum PeerAllowedReactions: Equatable, Codable {
private enum Discriminant: Int32 {
case all = 0
case limited = 1
case empty = 2
}
case all
case limited([MessageReaction.Reaction])
case empty
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let discriminant = try container.decode(Int32.self, forKey: "_d")
switch discriminant {
case Discriminant.all.rawValue:
self = .all
case Discriminant.limited.rawValue:
self = .limited(try container.decode([MessageReaction.Reaction].self, forKey: "r"))
case Discriminant.empty.rawValue:
self = .empty
default:
assertionFailure()
self = .all
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
switch self {
case .all:
try container.encode(Discriminant.all.rawValue, forKey: "_d")
case let .limited(reactions):
try container.encode(Discriminant.limited.rawValue, forKey: "_d")
try container.encode(reactions, forKey: "r")
case .empty:
try container.encode(Discriminant.empty.rawValue, forKey: "_d")
}
}
}
public final class CachedGroupData: CachedPeerData {
public let participants: CachedGroupParticipants?
public let exportedInvitation: ExportedInvitation?
@ -55,7 +98,8 @@ public final class CachedGroupData: CachedPeerData {
public let callJoinPeerId: PeerId?
public let themeEmoticon: String?
public let inviteRequestsPending: Int32?
public let allowedReactions: [MessageReaction.Reaction]?
public let allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>
public let peerIds: Set<PeerId>
public let messageIds: Set<MessageId>
@ -79,7 +123,7 @@ public final class CachedGroupData: CachedPeerData {
self.callJoinPeerId = nil
self.themeEmoticon = nil
self.inviteRequestsPending = nil
self.allowedReactions = nil
self.allowedReactions = .unknown
}
public init(
@ -98,7 +142,7 @@ public final class CachedGroupData: CachedPeerData {
callJoinPeerId: PeerId?,
themeEmoticon: String?,
inviteRequestsPending: Int32?,
allowedReactions: [MessageReaction.Reaction]?
allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>
) {
self.participants = participants
self.exportedInvitation = exportedInvitation
@ -180,10 +224,12 @@ public final class CachedGroupData: CachedPeerData {
self.inviteRequestsPending = decoder.decodeOptionalInt32ForKey("irp")
if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin)
if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = .known(.limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin)))
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
self.allowedReactions = .known(allowedReactions)
} else {
self.allowedReactions = nil
self.allowedReactions = .unknown
}
var messageIds = Set<MessageId>()
@ -276,17 +322,11 @@ public final class CachedGroupData: CachedPeerData {
encoder.encodeNil(forKey: "irp")
}
if let allowedReactions = self.allowedReactions {
encoder.encodeStringArray(allowedReactions.compactMap { item -> String? in
switch item {
case let .builtin(value):
return value
case .custom:
return nil
}
}, forKey: "allowedReactions")
} else {
encoder.encodeNil(forKey: "allowedReactions")
switch self.allowedReactions {
case .unknown:
encoder.encodeNil(forKey: "allowedReactionSet")
case let .known(value):
encoder.encode(value, forKey: "allowedReactionSet")
}
}
@ -370,7 +410,7 @@ public final class CachedGroupData: CachedPeerData {
return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, about: self.about, flags: self.flags, hasScheduledMessages: self.hasScheduledMessages, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, callJoinPeerId: self.callJoinPeerId, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, allowedReactions: self.allowedReactions)
}
public func withUpdatedAllowedReactions(_ allowedReactions: [MessageReaction.Reaction]?) -> CachedGroupData {
public func withUpdatedAllowedReactions(_ allowedReactions: EnginePeerCachedInfoItem<PeerAllowedReactions>) -> CachedGroupData {
return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, about: self.about, flags: self.flags, hasScheduledMessages: self.hasScheduledMessages, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, callJoinPeerId: self.callJoinPeerId, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, allowedReactions: allowedReactions)
}
}

View File

@ -9,6 +9,25 @@ public enum EnginePeerCachedInfoItem<T> {
case unknown
}
extension EnginePeerCachedInfoItem: Equatable where T: Equatable {
public static func ==(lhs: EnginePeerCachedInfoItem<T>, rhs: EnginePeerCachedInfoItem<T>) -> Bool {
switch lhs {
case let .known(value):
if case .known(value) = rhs {
return true
} else {
return false
}
case .unknown:
if case .unknown = rhs {
return true
} else {
return false
}
}
}
}
public enum EngineChannelParticipant: Equatable {
case creator(id: EnginePeer.Id, adminInfo: ChannelParticipantAdminInfo?, rank: String?)
case member(id: EnginePeer.Id, invitedAt: Int32, adminInfo: ChannelParticipantAdminInfo?, banInfo: ChannelParticipantBannedInfo?, rank: String?)
@ -452,7 +471,7 @@ public extension TelegramEngine.EngineData.Item {
}
public struct AllowedReactions: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = [MessageReaction.Reaction]?
public typealias Result = EnginePeerCachedInfoItem<PeerAllowedReactions>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
@ -476,7 +495,7 @@ public extension TelegramEngine.EngineData.Item {
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return cachedData.allowedReactions
} else {
return nil
return .unknown
}
}
}

View File

@ -694,7 +694,7 @@ public extension TelegramEngine {
return _internal_updatePeerSendAsPeer(account: self.account, peerId: peerId, sendAs: sendAs)
}
public func updatePeerAllowedReactions(peerId: PeerId, allowedReactions: [MessageReaction.Reaction]) -> Signal<Never, UpdatePeerAllowedReactionsError> {
public func updatePeerAllowedReactions(peerId: PeerId, allowedReactions: PeerAllowedReactions) -> Signal<Never, UpdatePeerAllowedReactionsError> {
return _internal_updatePeerAllowedReactions(account: account, peerId: peerId, allowedReactions: allowedReactions)
}

View File

@ -376,6 +376,20 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
}
}
let mappedAllowedReactions: PeerAllowedReactions
if let allowedReactions = allowedReactions {
switch allowedReactions {
case .chatReactionsAll:
mappedAllowedReactions = .all
case let .chatReactionsSome(reactions):
mappedAllowedReactions = .limited(reactions.compactMap(MessageReaction.Reaction.init(apiReaction:)))
case .chatReactionsNone:
mappedAllowedReactions = .empty
}
} else {
mappedAllowedReactions = .empty
}
return previous.withUpdatedParticipants(participants)
.withUpdatedExportedInvitation(exportedInvitation)
.withUpdatedBotInfos(botInfos)
@ -389,7 +403,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
.withUpdatedCallJoinPeerId(groupCallDefaultJoinAs?.peerId)
.withUpdatedThemeEmoticon(chatFullThemeEmoticon)
.withUpdatedInviteRequestsPending(chatFullRequestsPending)
.withUpdatedAllowedReactions(allowedReactions.flatMap({ $0.map(MessageReaction.Reaction.builtin) }) ?? [])
.withUpdatedAllowedReactions(.known(mappedAllowedReactions))
})
case .channelFull:
break
@ -602,6 +616,20 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
}
}
let mappedAllowedReactions: PeerAllowedReactions
if let allowedReactions = allowedReactions {
switch allowedReactions {
case .chatReactionsAll:
mappedAllowedReactions = .all
case let .chatReactionsSome(reactions):
mappedAllowedReactions = .limited(reactions.compactMap(MessageReaction.Reaction.init(apiReaction:)))
case .chatReactionsNone:
mappedAllowedReactions = .empty
}
} else {
mappedAllowedReactions = .empty
}
return previous.withUpdatedFlags(channelFlags)
.withUpdatedAbout(about)
.withUpdatedParticipantsSummary(CachedChannelParticipantsSummary(memberCount: participantsCount, adminCount: adminsCount, bannedCount: bannedCount, kickedCount: kickedCount))
@ -627,7 +655,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
.withUpdatedThemeEmoticon(themeEmoticon)
.withUpdatedInviteRequestsPending(requestsPending)
.withUpdatedSendAsPeerId(sendAsPeerId)
.withUpdatedAllowedReactions(allowedReactions.flatMap({ $0.map(MessageReaction.Reaction.builtin) }) ?? [])
.withUpdatedAllowedReactions(.known(mappedAllowedReactions))
})
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {

View File

@ -16963,12 +16963,18 @@ func peerAllowedReactions(context: AccountContext, peerId: PeerId) -> Signal<All
TelegramEngine.EngineData.Item.Peer.AllowedReactions(id: peerId)
)
|> map { peer, allowedReactions -> AllowedReactions? in
if let allowedReactions = allowedReactions {
return .set(Set(allowedReactions))
} else if case .user = peer {
return .all
} else {
switch allowedReactions {
case .unknown:
return nil
case let .known(value):
switch value {
case .all:
return .all
case let .limited(reactions):
return .set(Set(reactions))
case .empty:
return .set(Set())
}
}
}
}

View File

@ -1277,11 +1277,15 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
let label: String
if let cachedData = data.cachedData as? CachedChannelData, let allowedReactions = cachedData.allowedReactions {
if allowedReactions.isEmpty {
if let cachedData = data.cachedData as? CachedChannelData, case let .known(allowedReactions) = cachedData.allowedReactions {
switch allowedReactions {
case .all:
//TODO:localize
label = "Enabled"
case .empty:
label = presentationData.strings.PeerInfo_ReactionsDisabled
} else {
label = "\(allowedReactions.count)"
case let .limited(reactions):
label = "\(reactions.count)"
}
} else {
label = ""
@ -1439,11 +1443,15 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
let label: String
if let cachedData = data.cachedData as? CachedChannelData, let allowedReactions = cachedData.allowedReactions {
if allowedReactions.isEmpty {
if let cachedData = data.cachedData as? CachedChannelData, case let .known(allowedReactions) = cachedData.allowedReactions {
switch allowedReactions {
case .all:
//TODO:localize
label = "Enabled"
case .empty:
label = presentationData.strings.PeerInfo_ReactionsDisabled
} else {
label = "\(allowedReactions.count)"
case let .limited(reactions):
label = "\(reactions.count)"
}
} else {
label = ""
@ -1461,11 +1469,15 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
} else {
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
let label: String
if let cachedData = data.cachedData as? CachedChannelData, let allowedReactions = cachedData.allowedReactions {
if allowedReactions.isEmpty {
if let cachedData = data.cachedData as? CachedChannelData, case let .known(allowedReactions) = cachedData.allowedReactions {
switch allowedReactions {
case .all:
//TODO:localize
label = "Enabled"
case .empty:
label = presentationData.strings.PeerInfo_ReactionsDisabled
} else {
label = "\(allowedReactions.count)"
case let .limited(reactions):
label = "\(reactions.count)"
}
} else {
label = ""
@ -1571,11 +1583,15 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
do {
let label: String
if let cachedData = data.cachedData as? CachedGroupData, let allowedReactions = cachedData.allowedReactions {
if allowedReactions.isEmpty {
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
switch allowedReactions {
case .all:
//TODO:localize
label = "Enabled"
case .empty:
label = presentationData.strings.PeerInfo_ReactionsDisabled
} else {
label = "\(allowedReactions.count)"
case let .limited(reactions):
label = "\(reactions.count)"
}
} else {
label = ""