From 53de2b9dc0514f1a9a33ecd622f02b82513d9dbf Mon Sep 17 00:00:00 2001 From: Peter <> Date: Mon, 29 Jul 2019 19:07:45 +0300 Subject: [PATCH] Display error when sharing to a slowmode-restricted group --- .../TelegramUI/ChatController.swift | 25 +- ...atMessageInteractiveInstantVideoNode.swift | 2 +- .../ChatMessageInteractiveMediaNode.swift | 4 +- .../TelegramUI/FileMediaResourceStatus.swift | 2 +- .../PeerMediaCollectionController.swift | 2 +- .../Resources/PresentationStrings.mapping | Bin 120037 -> 120113 bytes .../TelegramUI/ShareController.swift | 228 +++++++++++------- .../TelegramUI/ShareControllerNode.swift | 13 +- 8 files changed, 168 insertions(+), 108 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift index e91427bed8..4723e91955 100644 --- a/submodules/TelegramUI/TelegramUI/ChatController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatController.swift @@ -3749,20 +3749,21 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, self.failedMessageEventsDisposable.set((self.context.account.pendingMessageManager.failedMessageEvents(peerId: peerId) |> deliverOnMainQueue).start(next: { [weak self] reason in if let strongSelf = self { - let subjectFlags: TelegramChatBannedRightsFlags = .banSendMedia - let text: String let moreInfo: Bool switch reason { - case .flood: - text = strongSelf.presentationData.strings.Conversation_SendMessageErrorFlood - moreInfo = true - case .publicBan: - text = strongSelf.presentationData.strings.Conversation_SendMessageErrorGroupRestricted - moreInfo = true - case .mediaRestricted: - strongSelf.interfaceInteraction?.displayRestrictedInfo(.mediaRecording, .alert) - return + case .flood: + text = strongSelf.presentationData.strings.Conversation_SendMessageErrorFlood + moreInfo = true + case .publicBan: + text = strongSelf.presentationData.strings.Conversation_SendMessageErrorGroupRestricted + moreInfo = true + case .mediaRestricted: + strongSelf.interfaceInteraction?.displayRestrictedInfo(.mediaRecording, .alert) + return + case .slowmodeActive: + text = strongSelf.presentationData.strings.Chat_SlowmodeSendError + moreInfo = false } let actions: [TextAlertAction] if moreInfo { @@ -5826,7 +5827,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, return nil } return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id) - |> mapToSignal { status -> Signal in + |> mapToSignal { status, _ -> Signal in if status != nil { return .never() } else { diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift index a14ea83239..3151b18fde 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift @@ -195,7 +195,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { var updatedPlaybackStatus: Signal? if let updatedFile = updatedFile, updatedMedia || updatedMessageId { - updatedPlaybackStatus = combineLatest(messageFileMediaResourceStatus(context: item.context, file: updatedFile, message: item.message, isRecentActions: item.associatedData.isRecentActions), item.context.account.pendingMessageManager.pendingMessageStatus(item.message.id)) + updatedPlaybackStatus = combineLatest(messageFileMediaResourceStatus(context: item.context, file: updatedFile, message: item.message, isRecentActions: item.associatedData.isRecentActions), item.context.account.pendingMessageManager.pendingMessageStatus(item.message.id) |> map { $0.0 }) |> map { resourceStatus, pendingStatus -> FileMediaResourceStatus in if let pendingStatus = pendingStatus { var progress = pendingStatus.progress diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift index 074ffc7141..c0f9be3518 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift @@ -555,7 +555,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { if statusUpdated { if let image = media as? TelegramMediaImage { if message.flags.isSending { - updatedStatusSignal = combineLatest(chatMessagePhotoStatus(context: context, messageId: message.id, photoReference: .message(message: MessageReference(message), media: image)), context.account.pendingMessageManager.pendingMessageStatus(message.id)) + updatedStatusSignal = combineLatest(chatMessagePhotoStatus(context: context, messageId: message.id, photoReference: .message(message: MessageReference(message), media: image)), context.account.pendingMessageManager.pendingMessageStatus(message.id) |> map { $0.0 }) |> map { resourceStatus, pendingStatus -> (MediaResourceStatus, MediaResourceStatus?) in if let pendingStatus = pendingStatus { let adjustedProgress = max(pendingStatus.progress, 0.027) @@ -571,7 +571,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { } } } else if let file = media as? TelegramMediaFile { - updatedStatusSignal = combineLatest(messageMediaFileStatus(context: context, messageId: message.id, file: file), context.account.pendingMessageManager.pendingMessageStatus(message.id)) + updatedStatusSignal = combineLatest(messageMediaFileStatus(context: context, messageId: message.id, file: file), context.account.pendingMessageManager.pendingMessageStatus(message.id) |> map { $0.0 }) |> map { resourceStatus, pendingStatus -> (MediaResourceStatus, MediaResourceStatus?) in if let pendingStatus = pendingStatus { let adjustedProgress = max(pendingStatus.progress, 0.027) diff --git a/submodules/TelegramUI/TelegramUI/FileMediaResourceStatus.swift b/submodules/TelegramUI/TelegramUI/FileMediaResourceStatus.swift index 7e332a5a4b..c148f57a0b 100644 --- a/submodules/TelegramUI/TelegramUI/FileMediaResourceStatus.swift +++ b/submodules/TelegramUI/TelegramUI/FileMediaResourceStatus.swift @@ -52,7 +52,7 @@ func messageFileMediaResourceStatus(context: AccountContext, file: TelegramMedia } if message.flags.isSending { - return combineLatest(messageMediaFileStatus(context: context, messageId: message.id, file: file), context.account.pendingMessageManager.pendingMessageStatus(message.id), playbackStatus) + return combineLatest(messageMediaFileStatus(context: context, messageId: message.id, file: file), context.account.pendingMessageManager.pendingMessageStatus(message.id) |> map { $0.0 }, playbackStatus) |> map { resourceStatus, pendingStatus, playbackStatus -> FileMediaResourceStatus in let mediaStatus: FileMediaResourceMediaStatus if let playbackStatus = playbackStatus { diff --git a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift index aeb8105776..c6f118151c 100644 --- a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift @@ -663,7 +663,7 @@ public class PeerMediaCollectionController: TelegramController { return nil } return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id) - |> mapToSignal { status -> Signal in + |> mapToSignal { status, _ -> Signal in if status != nil { return .never() } else { diff --git a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping index 0aee61edc8f6cae4ce94b5f68dddc37b29184100..8b57bd3f0a61d7cf0a90383216700f67dddcb511 100644 GIT binary patch delta 20297 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 delta 19718 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 I`Hb2A4+axtasU7T diff --git a/submodules/TelegramUI/TelegramUI/ShareController.swift b/submodules/TelegramUI/TelegramUI/ShareController.swift index 047436bf87..1e7be6f647 100644 --- a/submodules/TelegramUI/TelegramUI/ShareController.swift +++ b/submodules/TelegramUI/TelegramUI/ShareController.swift @@ -340,6 +340,11 @@ public final class ShareController: ViewController { override public func loadDisplayNode() { self.displayNode = ShareControllerNode(sharedContext: self.sharedContext, defaultAction: self.defaultAction, requestLayout: { [weak self] transition in self?.requestLayout(transition: transition) + }, presentError: { [weak self] title, text in + guard let strongSelf = self else { + return + } + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) }, externalShare: self.externalShare, immediateExternalShare: self.immediateExternalShare) self.controllerNode.dismiss = { [weak self] shared in self?.presentingViewController?.dismiss(animated: false, completion: nil) @@ -353,98 +358,141 @@ public final class ShareController: ViewController { }) } self.controllerNode.share = { [weak self] text, peerIds in - if let strongSelf = self { - switch strongSelf.subject { - case let .url(url): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - messages.append(.message(text: url, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .text(string): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - messages.append(.message(text: string, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .quote(string, url): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - let attributedText = NSMutableAttributedString(string: string, attributes: [ChatTextInputAttributes.italic: true as NSNumber]) - attributedText.append(NSAttributedString(string: "\n\n\(url)")) - let entities = generateChatInputTextEntities(attributedText) - messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .image(representations): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil)), replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .media(mediaReference): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - messages.append(.message(text: "", attributes: [], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .mapMedia(media): - for peerId in peerIds { - var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil)) - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages).start() - } - return .complete() - case let .messages(messages): - for peerId in peerIds { - var messagesToEnqueue: [EnqueueMessage] = [] - if !text.isEmpty { - messagesToEnqueue.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) - } - for message in messages { - messagesToEnqueue.append(.forward(source: message.id, grouping: .auto)) - } - let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messagesToEnqueue).start() - } - return .single(.done) - case let .fromExternal(f): - return f(peerIds, text, strongSelf.currentAccount) - |> map { state -> ShareState in - switch state { - case .preparing: - return .preparing - case let .progress(value): - return .progress(value) - case .done: - return .done - } - } + guard let strongSelf = self else { + return .complete() + } + var shareSignals: [Signal<[MessageId?], NoError>] = [] + switch strongSelf.subject { + case let .url(url): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + messages.append(.message(text: url, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .text(string): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + messages.append(.message(text: string, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .quote(string, url): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + let attributedText = NSMutableAttributedString(string: string, attributes: [ChatTextInputAttributes.italic: true as NSNumber]) + attributedText.append(NSAttributedString(string: "\n\n\(url)")) + let entities = generateChatInputTextEntities(attributedText) + messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .image(representations): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil)), replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .media(mediaReference): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + messages.append(.message(text: "", attributes: [], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .mapMedia(media): + for peerId in peerIds { + var messages: [EnqueueMessage] = [] + if !text.isEmpty { + messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil)) + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) + } + case let .messages(messages): + for peerId in peerIds { + var messagesToEnqueue: [EnqueueMessage] = [] + if !text.isEmpty { + messagesToEnqueue.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)) + } + for message in messages { + messagesToEnqueue.append(.forward(source: message.id, grouping: .auto)) + } + shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messagesToEnqueue)) + } + case let .fromExternal(f): + return f(peerIds, text, strongSelf.currentAccount) + |> map { state -> ShareState in + switch state { + case .preparing: + return .preparing + case let .progress(value): + return .progress(value) + case .done: + return .done + } } } - return .complete() + let account = strongSelf.currentAccount + let queue = Queue.mainQueue() + var displayedError = false + return combineLatest(queue: queue, shareSignals) + |> mapToSignal { messageIdSets -> Signal in + var statuses: [Signal<(MessageId, PendingMessageStatus?, PendingMessageFailureReason?), NoError>] = [] + for messageIds in messageIdSets { + for case let id? in messageIds { + statuses.append(account.pendingMessageManager.pendingMessageStatus(id) + |> map { status, error -> (MessageId, PendingMessageStatus?, PendingMessageFailureReason?) in + return (id, status, error) + }) + } + } + return combineLatest(queue: queue, statuses) + |> mapToSignal { statuses -> Signal in + var hasStatuses = false + for (id, status, error) in statuses { + if let error = error { + Queue.mainQueue().async { + let _ = (account.postbox.transaction { transaction -> Peer? in + transaction.deleteMessages([id]) + return transaction.getPeer(id.peerId) + } + |> deliverOnMainQueue).start(next: { peer in + guard let strongSelf = self, let peer = peer else { + return + } + if !displayedError, case .slowmodeActive = error { + displayedError = true + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: peer.displayTitle, text: strongSelf.presentationData.strings.Chat_SlowmodeSendError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + } + }) + } + } + let _ = account.postbox.transaction({ transaction in + + }).start() + if status != nil { + hasStatuses = true + } + } + if !hasStatuses { + return .single(.done) + } + return .complete() + } + |> take(1) + } } self.controllerNode.shareExternal = { [weak self] in if let strongSelf = self { diff --git a/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift b/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift index 257ba16385..2c513d1eff 100644 --- a/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift @@ -30,6 +30,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate private let defaultAction: ShareControllerAction? private let requestLayout: (ContainedViewLayoutTransition) -> Void + private let presentError: (String?, String) -> Void private var containerLayout: (ContainerViewLayout, CGFloat, CGFloat)? @@ -70,11 +71,12 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate private var hapticFeedback: HapticFeedback? - init(sharedContext: SharedAccountContext, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, externalShare: Bool, immediateExternalShare: Bool) { + init(sharedContext: SharedAccountContext, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, presentError: @escaping (String?, String) -> Void, externalShare: Bool, immediateExternalShare: Bool) { self.sharedContext = sharedContext self.presentationData = sharedContext.currentPresentationData.with { $0 } self.externalShare = externalShare self.immediateExternalShare = immediateExternalShare + self.presentError = presentError self.defaultAction = defaultAction self.requestLayout = requestLayout @@ -500,6 +502,15 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate defaultAction.action() } } else { + if !self.inputFieldNode.text.isEmpty { + for peer in self.controllerInteraction!.selectedPeers { + if let channel = peer.peer as? TelegramChannel, channel.isRestrictedBySlowmode { + self.presentError(channel.title, self.presentationData.strings.Share_MultipleMessagesDisabled) + return + } + } + } + self.inputFieldNode.deactivateInput() let transition = ContainedViewLayoutTransition.animated(duration: 0.12, curve: .easeInOut) transition.updateAlpha(node: self.actionButtonNode, alpha: 0.0)