diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 301643c9d1..86bf244d78 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -40,6 +40,7 @@ public enum ShareControllerExternalStatus { } public enum ShareControllerError { + case generic case fileTooBig(Int64) } @@ -551,6 +552,249 @@ public final class ShareController: ViewController { self?.presentingViewController?.dismiss(animated: false, completion: nil) }) } + + self.controllerNode.tryShare = { [weak self] text, peers in + guard let strongSelf = self else { + return false + } + + var subject = strongSelf.subject + if let segmentedValues = strongSelf.segmentedValues { + let selectedValue = segmentedValues[strongSelf.controllerNode.selectedSegmentedIndex] + subject = selectedValue.subject + } + + switch subject { + case .url: + for peer in peers { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + case .text: + for peer in peers { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + case .quote: + for peer in peers { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + case .image: + for peer in peers { + var banSendPhotos = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendPhotos) != nil { + banSendPhotos = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendPhotos) { + banSendPhotos = true + } + + if banSendPhotos { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + case let .media(mediaReference): + var sendTextAsCaption = false + if mediaReference.media is TelegramMediaImage || mediaReference.media is TelegramMediaFile { + sendTextAsCaption = true + } + + for peer in peers { + var banSendType = false + if mediaReference.media is TelegramMediaImage { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendPhotos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendPhotos) { + banSendType = true + } + } else if let file = mediaReference.media as? TelegramMediaFile { + if file.isSticker || file.isAnimated { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendStickers) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendStickers) { + banSendType = true + } + } else if file.isInstantVideo { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendInstantVideos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendInstantVideos) { + banSendType = true + } + } else if file.isVoice { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendVoice) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendVoice) { + banSendType = true + } + } else if file.isMusic { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendMusic) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendMusic) { + banSendType = true + } + } else if file.isVideo { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendVideos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendVideos) { + banSendType = true + } + } else { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendFiles) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendFiles) { + banSendType = true + } + } + } + + if banSendType { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + + if !text.isEmpty && !sendTextAsCaption { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + } + case .mapMedia: + for peer in peers { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + case let .messages(messages): + for peer in peers { + if !text.isEmpty { + var banSendText = false + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendText) != nil { + banSendText = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendText) { + banSendText = true + } + + if banSendText { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + for message in messages { + for media in message.media { + var banSendType = false + if media is TelegramMediaImage { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendPhotos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendPhotos) { + banSendType = true + } + } else if let file = media as? TelegramMediaFile { + if file.isSticker || file.isAnimated { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendStickers) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendStickers) { + banSendType = true + } + } else if file.isInstantVideo { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendInstantVideos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendInstantVideos) { + banSendType = true + } + } else if file.isVoice { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendVoice) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendVoice) { + banSendType = true + } + } else if file.isMusic { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendMusic) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendMusic) { + banSendType = true + } + } else if file.isVideo { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendVideos) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendVideos) { + banSendType = true + } + } else { + if case let .channel(channel) = peer, channel.hasBannedPermission(.banSendFiles) != nil { + banSendType = true + } else if case let .legacyGroup(group) = peer, group.hasBannedPermission(.banSendFiles) { + banSendType = true + } + } + } + + if banSendType { + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + + return false + } + } + } + } + case .fromExternal: + break + } + + return true + } + self.controllerNode.share = { [weak self] text, peerIds, topicIds, showNames, silently in guard let self else { return .complete() @@ -559,6 +803,7 @@ public final class ShareController: ViewController { return self.currentContext.engine.data.get(EngineDataMap( peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)) )) + |> deliverOnMainQueue |> castError(ShareControllerError.self) |> mapToSignal { [weak self] peers -> Signal in guard let strongSelf = self else { @@ -604,7 +849,7 @@ public final class ShareController: ViewController { if banSendText { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -637,7 +882,7 @@ public final class ShareController: ViewController { if banSendText { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -669,7 +914,7 @@ public final class ShareController: ViewController { if banSendText { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -704,7 +949,7 @@ public final class ShareController: ViewController { if banSendPhotos { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -778,7 +1023,7 @@ public final class ShareController: ViewController { if banSendType { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -810,7 +1055,7 @@ public final class ShareController: ViewController { if banSendText { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } var replyToMessageId: MessageId? @@ -851,7 +1096,7 @@ public final class ShareController: ViewController { if banSendText { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } messagesToEnqueue.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])) @@ -908,7 +1153,7 @@ public final class ShareController: ViewController { if banSendType { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), text: restrictedSendingContentsText(peer: peer, presentationData: strongSelf.presentationData), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - return .complete() + return .fail(.generic) } } diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index a1a3f1679b..baa67514a2 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -59,6 +59,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate var dismiss: ((Bool) -> Void)? var cancel: (() -> Void)? + var tryShare: ((String, [EnginePeer]) -> Bool)? var share: ((String, [PeerId], [PeerId: Int64], Bool, Bool) -> Signal)? var shareExternal: ((Bool) -> Signal)? var switchToAnotherAccount: (() -> Void)? @@ -770,6 +771,41 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate } func send(peerId: PeerId? = nil, showNames: Bool = true, silently: Bool = false) { + let peerIds: [PeerId] + if let peerId = peerId { + peerIds = [peerId] + } else { + peerIds = self.controllerInteraction!.selectedPeers.map { $0.peerId } + } + + if let context = self.context, let tryShare = self.tryShare { + let _ = (context.engine.data.get(EngineDataMap( + peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)) + )) + |> deliverOnMainQueue).start(next: { [weak self] peers in + guard let self else { + return + } + + var mappedPeers: [EnginePeer] = [] + for peerId in peerIds { + if let maybePeer = peers[peerId], let peer = maybePeer { + mappedPeers.append(peer) + } + } + + if !tryShare(self.inputFieldNode.text, mappedPeers) { + return + } + + self.commitSend(peerId: peerId, showNames: showNames, silently: silently) + }) + } else { + self.commitSend(peerId: peerId, showNames: showNames, silently: silently) + } + } + + private func commitSend(peerId: PeerId?, showNames: Bool, silently: Bool) { if !self.inputFieldNode.text.isEmpty { for peer in self.controllerInteraction!.selectedPeers { if case let .channel(channel) = peer.peer, channel.isRestrictedBySlowmode { @@ -889,6 +925,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate strongSelf.dismiss?(true) } } + }, error: { _ in + }, completed: { if !wasDone && fromForeignApp { doneImpl(false)