From 1020c3c4ae228eb428cafabf71651297b901b078 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 16 Oct 2020 23:37:17 +0400 Subject: [PATCH] Update API --- submodules/TelegramApi/Sources/Api0.swift | 3 +- submodules/TelegramApi/Sources/Api1.swift | 96 ++++--- .../Sources/AccountStateManagementUtils.swift | 27 +- .../TelegramCore/Sources/UpdateGroup.swift | 2 + .../Sources/UpdatePinnedMessage.swift | 244 +++++------------- .../TelegramUI/Sources/ChatController.swift | 14 +- 6 files changed, 126 insertions(+), 260 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 1a60414e04..a2840ab313 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -231,10 +231,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1893427255] = { return Api.Update.parse_updateChannelAvailableMessages($0) } dict[-513517117] = { return Api.Update.parse_updateDialogUnreadMark($0) } dict[1180041828] = { return Api.Update.parse_updateLangPackTooLong($0) } - dict[1279515160] = { return Api.Update.parse_updateUserPinnedMessage($0) } dict[-1398708869] = { return Api.Update.parse_updateMessagePoll($0) } dict[1421875280] = { return Api.Update.parse_updateChatDefaultBannedRights($0) } - dict[-519195831] = { return Api.Update.parse_updateChatPinnedMessage($0) } dict[422972864] = { return Api.Update.parse_updateFolderPeers($0) } dict[1852826908] = { return Api.Update.parse_updateDialogPinned($0) } dict[-99664734] = { return Api.Update.parse_updatePinnedDialogs($0) } @@ -258,6 +256,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1178116716] = { return Api.Update.parse_updateReadChannelDiscussionOutbox($0) } dict[610945826] = { return Api.Update.parse_updatePeerBlocked($0) } dict[-13975905] = { return Api.Update.parse_updateChannelUserTyping($0) } + dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) } dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($0) } dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index 6840de7b7d..ef5d09c5d1 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -6166,10 +6166,8 @@ public extension Api { case updateChannelAvailableMessages(channelId: Int32, availableMinId: Int32) case updateDialogUnreadMark(flags: Int32, peer: Api.DialogPeer) case updateLangPackTooLong(langCode: String) - case updateUserPinnedMessage(userId: Int32, id: Int32) case updateMessagePoll(flags: Int32, pollId: Int64, poll: Api.Poll?, results: Api.PollResults) case updateChatDefaultBannedRights(peer: Api.Peer, defaultBannedRights: Api.ChatBannedRights, version: Int32) - case updateChatPinnedMessage(chatId: Int32, id: Int32, version: Int32) case updateFolderPeers(folderPeers: [Api.FolderPeer], pts: Int32, ptsCount: Int32) case updateDialogPinned(flags: Int32, folderId: Int32?, peer: Api.DialogPeer) case updatePinnedDialogs(flags: Int32, folderId: Int32?, order: [Api.DialogPeer]?) @@ -6193,6 +6191,7 @@ public extension Api { case updateReadChannelDiscussionOutbox(channelId: Int32, topMsgId: Int32, readMaxId: Int32) case updatePeerBlocked(peerId: Api.Peer, blocked: Api.Bool) case updateChannelUserTyping(flags: Int32, channelId: Int32, topMsgId: Int32?, userId: Int32, action: Api.SendMessageAction) + case updatePinnedMessages(flags: Int32, peer: Api.Peer, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedChannelMessages(flags: Int32, channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { @@ -6677,13 +6676,6 @@ public extension Api { } serializeString(langCode, buffer: buffer, boxed: false) break - case .updateUserPinnedMessage(let userId, let id): - if boxed { - buffer.appendInt32(1279515160) - } - serializeInt32(userId, buffer: buffer, boxed: false) - serializeInt32(id, buffer: buffer, boxed: false) - break case .updateMessagePoll(let flags, let pollId, let poll, let results): if boxed { buffer.appendInt32(-1398708869) @@ -6701,14 +6693,6 @@ public extension Api { defaultBannedRights.serialize(buffer, true) serializeInt32(version, buffer: buffer, boxed: false) break - case .updateChatPinnedMessage(let chatId, let id, let version): - if boxed { - buffer.appendInt32(-519195831) - } - serializeInt32(chatId, buffer: buffer, boxed: false) - serializeInt32(id, buffer: buffer, boxed: false) - serializeInt32(version, buffer: buffer, boxed: false) - break case .updateFolderPeers(let folderPeers, let pts, let ptsCount): if boxed { buffer.appendInt32(422972864) @@ -6916,6 +6900,20 @@ public extension Api { serializeInt32(userId, buffer: buffer, boxed: false) action.serialize(buffer, true) break + case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount): + if boxed { + buffer.appendInt32(-309990731) + } + serializeInt32(flags, buffer: buffer, boxed: false) + peer.serialize(buffer, true) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(messages.count)) + for item in messages { + serializeInt32(item, buffer: buffer, boxed: false) + } + serializeInt32(pts, buffer: buffer, boxed: false) + serializeInt32(ptsCount, buffer: buffer, boxed: false) + break case .updatePinnedChannelMessages(let flags, let channelId, let messages, let pts, let ptsCount): if boxed { buffer.appendInt32(-2054649973) @@ -7051,14 +7049,10 @@ public extension Api { return ("updateDialogUnreadMark", [("flags", flags), ("peer", peer)]) case .updateLangPackTooLong(let langCode): return ("updateLangPackTooLong", [("langCode", langCode)]) - case .updateUserPinnedMessage(let userId, let id): - return ("updateUserPinnedMessage", [("userId", userId), ("id", id)]) case .updateMessagePoll(let flags, let pollId, let poll, let results): return ("updateMessagePoll", [("flags", flags), ("pollId", pollId), ("poll", poll), ("results", results)]) case .updateChatDefaultBannedRights(let peer, let defaultBannedRights, let version): return ("updateChatDefaultBannedRights", [("peer", peer), ("defaultBannedRights", defaultBannedRights), ("version", version)]) - case .updateChatPinnedMessage(let chatId, let id, let version): - return ("updateChatPinnedMessage", [("chatId", chatId), ("id", id), ("version", version)]) case .updateFolderPeers(let folderPeers, let pts, let ptsCount): return ("updateFolderPeers", [("folderPeers", folderPeers), ("pts", pts), ("ptsCount", ptsCount)]) case .updateDialogPinned(let flags, let folderId, let peer): @@ -7105,6 +7099,8 @@ public extension Api { return ("updatePeerBlocked", [("peerId", peerId), ("blocked", blocked)]) case .updateChannelUserTyping(let flags, let channelId, let topMsgId, let userId, let action): return ("updateChannelUserTyping", [("flags", flags), ("channelId", channelId), ("topMsgId", topMsgId), ("userId", userId), ("action", action)]) + case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount): + return ("updatePinnedMessages", [("flags", flags), ("peer", peer), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) case .updatePinnedChannelMessages(let flags, let channelId, let messages, let pts, let ptsCount): return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) } @@ -8070,20 +8066,6 @@ public extension Api { return nil } } - public static func parse_updateUserPinnedMessage(_ reader: BufferReader) -> Update? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - if _c1 && _c2 { - return Api.Update.updateUserPinnedMessage(userId: _1!, id: _2!) - } - else { - return nil - } - } public static func parse_updateMessagePoll(_ reader: BufferReader) -> Update? { var _1: Int32? _1 = reader.readInt32() @@ -8129,23 +8111,6 @@ public extension Api { return nil } } - public static func parse_updateChatPinnedMessage(_ reader: BufferReader) -> Update? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - var _3: Int32? - _3 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.Update.updateChatPinnedMessage(chatId: _1!, id: _2!, version: _3!) - } - else { - return nil - } - } public static func parse_updateFolderPeers(_ reader: BufferReader) -> Update? { var _1: [Api.FolderPeer]? if let _ = reader.readInt32() { @@ -8558,6 +8523,33 @@ public extension Api { return nil } } + public static func parse_updatePinnedMessages(_ reader: BufferReader) -> Update? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Api.Peer? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.Peer + } + var _3: [Int32]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self) + } + var _4: Int32? + _4 = reader.readInt32() + var _5: Int32? + _5 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.Update.updatePinnedMessages(flags: _1!, peer: _2!, messages: _3!, pts: _4!, ptsCount: _5!) + } + else { + return nil + } + } public static func parse_updatePinnedChannelMessages(_ reader: BufferReader) -> Update? { var _1: Int32? _1 = reader.readInt32() diff --git a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift index fd260485c3..62133159be 100644 --- a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift @@ -873,6 +873,11 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo updatedState.updateMinAvailableMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: minId)) case let .updateDeleteMessages(messages, _, _): updatedState.deleteMessagesWithGlobalIds(messages) + case let .updatePinnedMessages(flags, peer, messages, _, _): + let peerId = peer.peerId + updatedState.updateMessagesPinned(ids: messages.map { id in + MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: id) + }, pinned: (flags & (1 << 0)) != 0) case let .updateEditMessage(apiMessage, _, _): if let message = StoreMessage(apiMessage: apiMessage), case let .Id(messageId) = message.id { if let preCachedResources = apiMessage.preCachedResources { @@ -1139,28 +1144,6 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo channelsToPoll.insert(peerId) } } - case let .updateUserPinnedMessage(userId, id): - let userPeerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) - updatedState.updateCachedPeerData(userPeerId, { current in - let previous: CachedUserData - if let current = current as? CachedUserData { - previous = current - } else { - previous = CachedUserData() - } - return previous.withUpdatedPinnedMessageId(id == 0 ? nil : MessageId(peerId: userPeerId, namespace: Namespaces.Message.Cloud, id: id)) - }) - case let .updateChatPinnedMessage(groupId, id, _): - let groupPeerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: groupId) - updatedState.updateCachedPeerData(groupPeerId, { current in - let previous: CachedGroupData - if let current = current as? CachedGroupData { - previous = current - } else { - previous = CachedGroupData() - } - return previous.withUpdatedPinnedMessageId(id == 0 ? nil : MessageId(peerId: groupPeerId, namespace: Namespaces.Message.Cloud, id: id)) - }) case let .updatePeerBlocked(peerId, blocked): let userPeerId = peerId.peerId updatedState.updateCachedPeerData(userPeerId, { current in diff --git a/submodules/TelegramCore/Sources/UpdateGroup.swift b/submodules/TelegramCore/Sources/UpdateGroup.swift index 8145e9d2e9..8ae8b4c168 100644 --- a/submodules/TelegramCore/Sources/UpdateGroup.swift +++ b/submodules/TelegramCore/Sources/UpdateGroup.swift @@ -80,6 +80,8 @@ func apiUpdatePtsRange(_ update: Api.Update) -> (Int32, Int32)? { } else { return nil } + case let .updatePinnedMessages(_, _, _, pts, ptsCount): + return (pts, ptsCount) default: return nil } diff --git a/submodules/TelegramCore/Sources/UpdatePinnedMessage.swift b/submodules/TelegramCore/Sources/UpdatePinnedMessage.swift index a2a6b6bb1d..baa8233d92 100644 --- a/submodules/TelegramCore/Sources/UpdatePinnedMessage.swift +++ b/submodules/TelegramCore/Sources/UpdatePinnedMessage.swift @@ -25,185 +25,83 @@ public func requestUpdatePinnedMessage(account: Account, peerId: PeerId, update: guard let peer = peer, let inputPeer = apiInputPeer(peer) else { return .fail(.generic) } - if let channel = peer as? TelegramChannel, let inputPeer = apiInputPeer(channel) { + + if let channel = peer as? TelegramChannel { let canManagePin = channel.hasPermission(.pinMessages) + if !canManagePin { + return .fail(.generic) + } + } else if let group = peer as? TelegramGroup { + switch group.role { + case .creator, .admin: + break + default: + if let defaultBannedRights = group.defaultBannedRights { + if defaultBannedRights.flags.contains(.banPinMessages) { + return .fail(.generic) + } + } + } + } else if let _ = peer as? TelegramUser, let cachedPeerData = cachedPeerData as? CachedUserData { + if !cachedPeerData.canPinMessages { + return .fail(.generic) + } + } - if canManagePin { - var flags: Int32 = 0 - let messageId: Int32 - switch update { - case let .pin(id, silent): - messageId = id.id - if silent { - flags |= (1 << 0) - } - case let .clear(id): - messageId = id.id - flags |= 1 << 1 - } - - let request = Api.functions.messages.updatePinnedMessage(flags: flags, peer: inputPeer, id: messageId) - - return account.network.request(request) - |> mapError { _ -> UpdatePinnedMessageError in - return .generic - } - |> mapToSignal { updates -> Signal in - account.stateManager.addUpdates(updates) - return account.postbox.transaction { transaction in - switch updates { - case let .updates(updates, _, _, _, _): - if updates.isEmpty { - if peerId.namespace == Namespaces.Peer.CloudChannel { - let messageId: MessageId - switch update { - case let .pin(id, _): - messageId = id - case let .clear(id): - messageId = id - } - transaction.updateMessage(messageId, update: { currentMessage in - let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init) - var updatedTags = currentMessage.tags - switch update { - case .pin: - updatedTags.insert(.pinned) - case .clear: - updatedTags.remove(.pinned) - } - if updatedTags == currentMessage.tags { - return .skip - } - return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: currentMessage.attributes, media: currentMessage.media)) - }) - } - } - default: - break - } - /*transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in - if let current = current as? CachedChannelData { - let pinnedMessageId: MessageId? - switch update { - case let .pin(id, _): - pinnedMessageId = id - case .clear: - pinnedMessageId = nil - } - return current.withUpdatedPinnedMessageId(pinnedMessageId) - } else { - return current - } - })*/ - } - |> mapError { _ -> UpdatePinnedMessageError in - } - } - } else { - return .fail(.generic) + var flags: Int32 = 0 + let messageId: Int32 + switch update { + case let .pin(id, silent): + messageId = id.id + if silent { + flags |= (1 << 0) } - } else { - var canPin = false - if let group = peer as? TelegramGroup { - switch group.role { - case .creator, .admin: - canPin = true - default: - if let defaultBannedRights = group.defaultBannedRights { - canPin = !defaultBannedRights.flags.contains(.banPinMessages) - } else { - canPin = true + case let .clear(id): + messageId = id.id + flags |= 1 << 1 + } + + let request = Api.functions.messages.updatePinnedMessage(flags: flags, peer: inputPeer, id: messageId) + + return account.network.request(request) + |> mapError { _ -> UpdatePinnedMessageError in + return .generic + } + |> mapToSignal { updates -> Signal in + account.stateManager.addUpdates(updates) + return account.postbox.transaction { transaction in + switch updates { + case let .updates(updates, _, _, _, _): + if updates.isEmpty { + if peerId.namespace == Namespaces.Peer.CloudChannel { + let messageId: MessageId + switch update { + case let .pin(id, _): + messageId = id + case let .clear(id): + messageId = id + } + transaction.updateMessage(messageId, update: { currentMessage in + let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init) + var updatedTags = currentMessage.tags + switch update { + case .pin: + updatedTags.insert(.pinned) + case .clear: + updatedTags.remove(.pinned) + } + if updatedTags == currentMessage.tags { + return .skip + } + return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: currentMessage.attributes, media: currentMessage.media)) + }) } + } + default: + break } - } else if let _ = peer as? TelegramUser, let cachedPeerData = cachedPeerData as? CachedUserData { - canPin = cachedPeerData.canPinMessages } - if canPin { - var flags: Int32 = 0 - let messageId: Int32 - switch update { - case let .pin(id, silent): - messageId = id.id - if silent { - flags |= (1 << 0) - } - case let .clear(id): - messageId = id.id - flags |= 1 << 1 - } - - let request = Api.functions.messages.updatePinnedMessage(flags: flags, peer: inputPeer, id: messageId) - - return account.network.request(request) - |> mapError { _ -> UpdatePinnedMessageError in - return .generic - } - |> mapToSignal { updates -> Signal in - account.stateManager.addUpdates(updates) - return account.postbox.transaction { transaction in - switch updates { - case let .updates(updates, _, _, _, _): - if updates.isEmpty { - if peerId.namespace == Namespaces.Peer.CloudChannel { - let messageId: MessageId - switch update { - case let .pin(id, _): - messageId = id - case let .clear(id): - messageId = id - } - transaction.updateMessage(messageId, update: { currentMessage in - let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init) - var updatedTags = currentMessage.tags - switch update { - case .pin: - updatedTags.insert(.pinned) - case .clear: - updatedTags.remove(.pinned) - } - if updatedTags == currentMessage.tags { - return .skip - } - return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: currentMessage.attributes, media: currentMessage.media)) - }) - } - } - default: - break - } - - transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in - if let _ = peer as? TelegramGroup { - let current = current as? CachedGroupData ?? CachedGroupData() - let pinnedMessageId: MessageId? - switch update { - case let .pin(id, _): - pinnedMessageId = id - case .clear: - pinnedMessageId = nil - } - return current.withUpdatedPinnedMessageId(pinnedMessageId) - } else if let _ = peer as? TelegramUser { - let current = current as? CachedUserData ?? CachedUserData() - - let pinnedMessageId: MessageId? - switch update { - case let .pin(id, _): - pinnedMessageId = id - case .clear: - pinnedMessageId = nil - } - return current.withUpdatedPinnedMessageId(pinnedMessageId) - } else { - return current - } - }) - } - |> mapError { _ -> UpdatePinnedMessageError in - } - } - } else { - return .fail(.generic) + |> mapError { _ -> UpdatePinnedMessageError in } } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index c700d4616b..69c21fd979 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3242,7 +3242,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private func topPinnedMessageSignal(latest: Bool) -> Signal { let topPinnedMessage: Signal switch self.chatLocation { - case let .peer(peerId) where peerId.namespace == Namespaces.Peer.CloudChannel: + case let .peer(peerId): let replyHistory: Signal = (chatHistoryViewForLocation(ChatHistoryLocationInput(content: .Initial(count: 100), id: 0), context: self.context, chatLocation: .peer(peerId), chatLocationContextHolder: Atomic(value: nil), scheduled: false, fixedCombinedReadStates: nil, tagMask: MessageTags.pinned, additionalData: []) |> castError(Bool.self) |> mapToSignal { update -> Signal in @@ -3554,16 +3554,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } case let .peer(peerId): - if peerId.namespace == Namespaces.Peer.CloudChannel { - pinnedMessageId = topPinnedMessage?.message.id - pinnedMessage = topPinnedMessage - } else { - if let pinnedMessageId = pinnedMessageId { - if let message = messages?[pinnedMessageId] { - pinnedMessage = ChatPinnedMessage(message: message, topMessageId: message.id) - } - } - } + pinnedMessageId = topPinnedMessage?.message.id + pinnedMessage = topPinnedMessage } var pinnedMessageUpdated = false