diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 39d175126d..0af2c94adf 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7239,3 +7239,6 @@ Sorry for the inconvenience."; "Share.ShareMessage" = "Share Message"; "Conversation.UserSendMessage" = "SEND MESSAGE"; + +"Conversation.CopyProtectionForwardingDisabledBot" = "Forwards from this bot are restricted"; +"Conversation.CopyProtectionSavingDisabledBot" = "Saving from this bot is restricted"; diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 8529e8b1e8..5d2b5900f8 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -618,19 +618,30 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo } |> deliverOnMainQueue).start(next: { messages in if let strongSelf = self, !messages.isEmpty { - var isChannel = false + enum PeerType { + case group + case channel + case bot + } + var type: PeerType = .group for message in messages { - if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { - isChannel = true + if let user = message.author?._asPeer() as? TelegramUser, user.botInfo != nil { + type = .bot + break + } else if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { + type = .channel break } } let text: String - if save { - text = isChannel ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledGroup - } else { - text = isChannel ? strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledGroup + switch type { + case .group: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledGroup : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledGroup + case .channel: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledChannel + case .bot: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledBot : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledBot } strongSelf.copyProtectionTooltipController?.dismiss() diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index 00a3d34829..729d28e05b 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -809,23 +809,23 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate })) } - if strongSelf.fromPublicChannel, let context = strongSelf.context, let node = node as? ContextReferenceContentNode { - let presentationData = strongSelf.presentationData - let items: [ContextMenuItem] = [ - .action(ContextMenuActionItem(text: presentationData.strings.Share_ShareAsLink, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor) }, action: { _, f in - f(.default) - proceed(false) - })), - .action(ContextMenuActionItem(text: presentationData.strings.Share_ShareAsImage, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Image"), color: theme.contextMenu.primaryColor) }, action: { _, f in - f(.default) - proceed(true) - })) - ] - let contextController = ContextController(account: context.account, presentationData: presentationData, source: .reference(ShareContextReferenceContentSource(sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) - strongSelf.present?(contextController) - } else { +// if strongSelf.fromPublicChannel, let context = strongSelf.context, let node = node as? ContextReferenceContentNode { +// let presentationData = strongSelf.presentationData +// let items: [ContextMenuItem] = [ +// .action(ContextMenuActionItem(text: presentationData.strings.Share_ShareAsLink, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor) }, action: { _, f in +// f(.default) +// proceed(false) +// })), +// .action(ContextMenuActionItem(text: presentationData.strings.Share_ShareAsImage, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Image"), color: theme.contextMenu.primaryColor) }, action: { _, f in +// f(.default) +// proceed(true) +// })) +// ] +// let contextController = ContextController(account: context.account, presentationData: presentationData, source: .reference(ShareContextReferenceContentSource(sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) +// strongSelf.present?(contextController) +// } else { proceed(false) - } +// } } peersContentNode.openShare = { node, gesture in openShare(false, node, gesture) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 8ad640c2ae..247a262e15 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -1979,11 +1979,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }, openMessageShareMenu: { [weak self] id in if let strongSelf = self, let messages = strongSelf.chatDisplayNode.historyNode.messageGroupInCurrentHistoryView(id), let _ = messages.first { let shareController = ShareController(context: strongSelf.context, subject: .messages(messages), updatedPresentationData: strongSelf.updatedPresentationData, shareAsLink: true) - shareController.openShareAsImage = { [weak self] messages in - if let strongSelf = self { - strongSelf.present(ChatQrCodeScreen(context: strongSelf.context, subject: .messages(messages)), in: .window(.root)) - } - } +// shareController.openShareAsImage = { [weak self] messages in +// if let strongSelf = self { +// strongSelf.present(ChatQrCodeScreen(context: strongSelf.context, subject: .messages(messages)), in: .window(.root)) +// } +// } shareController.dismissed = { [weak self] shared in if shared { self?.commitPurposefulAction() @@ -7885,35 +7885,69 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }, presentChatRequestAdminInfo: { [weak self] in self?.presentChatRequestAdminInfo() }, displayCopyProtectionTip: { [weak self] node, save in - if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { - let isChannel: Bool - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - isChannel = true - } else { - isChannel = false - } - let text: String - if save { - text = isChannel ? strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionSavingDisabledGroup - } else { - text = isChannel ? strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionForwardingDisabledChannel : strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionForwardingDisabledGroup - } - - strongSelf.copyProtectionTooltipController?.dismiss() - let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) - strongSelf.copyProtectionTooltipController = tooltipController - tooltipController.dismissed = { [weak tooltipController] _ in - if let strongSelf = self, let tooltipController = tooltipController, strongSelf.copyProtectionTooltipController === tooltipController { - strongSelf.copyProtectionTooltipController = nil + if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer, let messageIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds { + let _ = (strongSelf.context.account.postbox.transaction { transaction -> [EngineMessage] in + var messages: [EngineMessage] = [] + for id in messageIds { + if let message = transaction.getMessage(id) { + messages.append(EngineMessage(message)) + } } + return messages } - strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { - if let strongSelf = self { - let rect = node.view.convert(node.view.bounds, to: strongSelf.chatDisplayNode.view).offsetBy(dx: 0.0, dy: 3.0) - return (strongSelf.chatDisplayNode, rect) + |> deliverOnMainQueue).start(next: { [weak self] messages in + guard let strongSelf = self else { + return } - return nil - })) + enum PeerType { + case group + case channel + case bot + } + var isBot = false + for message in messages { + if let author = message.author, case let .user(user) = author, user.botInfo != nil { + isBot = true + break + } + } + let type: PeerType + if isBot { + type = .bot + } else if let user = peer as? TelegramUser, user.botInfo != nil { + type = .bot + } else if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + type = .channel + } else { + type = .group + } + + let text: String + switch type { + case .group: + text = save ? strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionSavingDisabledGroup : strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionForwardingDisabledGroup + case .channel: + text = save ? strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionForwardingDisabledChannel + case .bot: + text = save ? strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionSavingDisabledBot : strongSelf.presentationInterfaceState.strings.Conversation_CopyProtectionForwardingDisabledBot + } + + strongSelf.copyProtectionTooltipController?.dismiss() + let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) + strongSelf.copyProtectionTooltipController = tooltipController + tooltipController.dismissed = { [weak tooltipController] _ in + if let strongSelf = self, let tooltipController = tooltipController, strongSelf.copyProtectionTooltipController === tooltipController { + strongSelf.copyProtectionTooltipController = nil + } + } + strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { + if let strongSelf = self { + let rect = node.view.convert(node.view.bounds, to: strongSelf.chatDisplayNode.view).offsetBy(dx: 0.0, dy: 3.0) + return (strongSelf.chatDisplayNode, rect) + } + return nil + })) + }) } }, statuses: ChatPanelInterfaceInteractionStatuses(editingMessage: self.editingMessage.get(), startingBot: self.startingBot.get(), unblockingPeer: self.unblockingPeer.get(), searching: self.searching.get(), loadingMessage: self.loadingMessage.get(), inlineSearch: self.performingInlineSearch.get())) diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 3000b2b7bd..e1dc4b61eb 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1111,7 +1111,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState } if data.messageActions.options.contains(.forward) { - if chatPresentationInterfaceState.copyProtectionEnabled { + if chatPresentationInterfaceState.copyProtectionEnabled || message.isCopyProtected() { } else { actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuForward, icon: { theme in @@ -1508,7 +1508,7 @@ func chatAvailableMessageActionsImpl(postbox: Postbox, accountPeerId: PeerId, me } } } else if let user = peer as? TelegramUser { - if !isScheduled && message.id.peerId.namespace != Namespaces.Peer.SecretChat && !message.containsSecretMedia && !isAction && !message.id.peerId.isReplies { + if !isScheduled && message.id.peerId.namespace != Namespaces.Peer.SecretChat && !message.containsSecretMedia && !isAction && !message.id.peerId.isReplies && !message.isCopyProtected() { if !(message.flags.isSending || message.flags.contains(.Failed)) { optionsMap[id]!.insert(.forward) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index b24486a1c9..826b047c78 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -6567,35 +6567,69 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate self?.controller?.push(c) }, completion: { _, _ in }), in: .window(.root)) }, displayCopyProtectionTip: { [weak self] node, save in - if let strongSelf = self, let peer = strongSelf.data?.peer { - let isChannel: Bool - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - isChannel = true - } else { - isChannel = false - } - let text: String - if save { - text = isChannel ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledGroup - } else { - text = isChannel ? strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledGroup - } - - strongSelf.copyProtectionTooltipController?.dismiss() - let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) - strongSelf.copyProtectionTooltipController = tooltipController - tooltipController.dismissed = { [weak tooltipController] _ in - if let strongSelf = self, let tooltipController = tooltipController, strongSelf.copyProtectionTooltipController === tooltipController { - strongSelf.copyProtectionTooltipController = nil + if let strongSelf = self, let peer = strongSelf.data?.peer, let messageIds = strongSelf.state.selectedMessageIds, !messageIds.isEmpty { + let _ = (strongSelf.context.account.postbox.transaction { transaction -> [EngineMessage] in + var messages: [EngineMessage] = [] + for id in messageIds { + if let message = transaction.getMessage(id) { + messages.append(EngineMessage(message)) + } } + return messages } - strongSelf.controller?.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { - if let strongSelf = self { - let rect = node.view.convert(node.view.bounds, to: strongSelf.view).offsetBy(dx: 0.0, dy: 3.0) - return (strongSelf, rect) + |> deliverOnMainQueue).start(next: { [weak self] messages in + guard let strongSelf = self else { + return } - return nil - })) + enum PeerType { + case group + case channel + case bot + } + var isBot = false + for message in messages { + if let author = message.author, case let .user(user) = author, user.botInfo != nil { + isBot = true + break + } + } + let type: PeerType + if isBot { + type = .bot + } else if let user = peer as? TelegramUser, user.botInfo != nil { + type = .bot + } else if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + type = .channel + } else { + type = .group + } + + let text: String + switch type { + case .group: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledGroup : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledGroup + case .channel: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledChannel : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledChannel + case .bot: + text = save ? strongSelf.presentationData.strings.Conversation_CopyProtectionSavingDisabledBot : strongSelf.presentationData.strings.Conversation_CopyProtectionForwardingDisabledBot + } + + strongSelf.copyProtectionTooltipController?.dismiss() + let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) + strongSelf.copyProtectionTooltipController = tooltipController + tooltipController.dismissed = { [weak tooltipController] _ in + if let strongSelf = self, let tooltipController = tooltipController, strongSelf.copyProtectionTooltipController === tooltipController { + strongSelf.copyProtectionTooltipController = nil + } + } + strongSelf.controller?.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { + if let strongSelf = self { + let rect = node.view.convert(node.view.bounds, to: strongSelf.view).offsetBy(dx: 0.0, dy: 3.0) + return (strongSelf, rect) + } + return nil + })) + }) } }) self.paneContainerNode.selectionPanelNode = selectionPanelNode