diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index 0fc26d8b85..edc62d5d9b 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -2950,8 +2950,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY case let .custom(getOverflow): let overflow = getOverflow(itemNode) - offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY - offset += floor(overflow - (self.visibleSize.height - insets.bottom - insets.top) * 0.5) + offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + itemNode.insets.top + offset += overflow + offset -= floor((self.visibleSize.height - insets.bottom - insets.top) * 0.5) //offset += 100.0 //offset = (self.visibleSize.height - insets.bottom) - itemNode.apparentFrame.maxY + getOverflow(itemNode) diff --git a/submodules/Pasteboard/Sources/Pasteboard.swift b/submodules/Pasteboard/Sources/Pasteboard.swift index 653b04ffd7..93c62c6ac7 100644 --- a/submodules/Pasteboard/Sources/Pasteboard.swift +++ b/submodules/Pasteboard/Sources/Pasteboard.swift @@ -38,6 +38,18 @@ private func rtfStringWithAppliedEntities(_ text: String, entities: [MessageText } } +struct AppSpecificPasteboardString: Codable { + var text: String + var entities: [MessageTextEntity] +} + +private func appSpecificStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> Data { + guard let data = try? JSONEncoder().encode(AppSpecificPasteboardString(text: text, entities: entities)) else { + return Data() + } + return data +} + private func chatInputStateString(attributedString: NSAttributedString) -> NSAttributedString? { let string = NSMutableAttributedString(string: attributedString.string) attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: [], using: { attributes, range, _ in @@ -100,12 +112,20 @@ public func chatInputStateStringFromRTF(_ data: Data, type: NSAttributedString.D return nil } +public func chatInputStateStringFromAppSpecificString(data: Data) -> NSAttributedString? { + guard let string = try? JSONDecoder().decode(AppSpecificPasteboardString.self, from: data) else { + return nil + } + return chatInputStateStringWithAppliedEntities(string.text, entities: string.entities) +} + public func storeMessageTextInPasteboard(_ text: String, entities: [MessageTextEntity]?) { var items: [String: Any] = [:] items[kUTTypeUTF8PlainText as String] = text if let entities = entities { items[kUTTypeRTF as String] = rtfStringWithAppliedEntities(text, entities: entities) + items["private.telegramtext"] = appSpecificStringWithAppliedEntities(text, entities: entities) } UIPasteboard.general.items = [items] } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift index d3becdeda8..fb65888d27 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -303,7 +303,8 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let replyRecognizer = ChatSwipeToReplyRecognizer(target: self, action: #selector(self.swipeToReplyGesture(_:))) if let item = self.item { - replyRecognizer.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + let _ = item + replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply self.view.disablesInteractiveTransitionGestureRecognizer = true } replyRecognizer.shouldBegin = { [weak self] in @@ -367,9 +368,9 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { private var setupTimestamp: Double? private func setupNode(item: ChatMessageItem) { - self.replyRecognizer?.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.replyRecognizer?.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply if self.isNodeLoaded { - self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply } guard self.animationNode == nil else { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index 8337ae7e81..c699bc663f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -730,8 +730,8 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { actualSize.height += textBottomSpacing if let (_, inlineMediaSize) = inlineMediaAndSize { - if actualSize.height < insets.top + inlineMediaEdgeInset + inlineMediaSize.height + inlineMediaEdgeInset { - actualSize.height = insets.top + inlineMediaEdgeInset + inlineMediaSize.height + inlineMediaEdgeInset + if actualSize.height < backgroundInsets.top + inlineMediaEdgeInset + inlineMediaSize.height + inlineMediaEdgeInset { + actualSize.height = backgroundInsets.top + inlineMediaEdgeInset + inlineMediaSize.height + inlineMediaEdgeInset } } case .media: diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 6bec504732..a9cf6b8602 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -1159,8 +1159,9 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI let replyRecognizer = ChatSwipeToReplyRecognizer(target: self, action: #selector(self.swipeToReplyGesture(_:))) if let item = self.item { - replyRecognizer.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply - self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + let _ = item + replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply } replyRecognizer.shouldBegin = { [weak self] in if let strongSelf = self, let item = strongSelf.item { @@ -2813,8 +2814,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI strongSelf.authorNameColor = authorNameColor - strongSelf.replyRecognizer?.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply - strongSelf.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + strongSelf.replyRecognizer?.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + strongSelf.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply var animation = animation if strongSelf.mainContextSourceNode.isExtractedToContextPreview { @@ -3613,6 +3614,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI if case let .System(duration, _) = animation/*, !strongSelf.mainContextSourceNode.isExtractedToContextPreview*/ { if !strongSelf.backgroundNode.frame.equalTo(backgroundFrame) { if useDisplayLinkAnimations { + strongSelf.clippingNode.clipsToBounds = shouldClipOnTransitions let backgroundAnimation = ListViewAnimation(from: strongSelf.backgroundNode.frame, to: backgroundFrame, duration: duration * UIView.animationDurationFactor(), curve: strongSelf.preferredAnimationCurve, beginAt: beginAt, update: { [weak strongSelf] _, frame in if let strongSelf = strongSelf { strongSelf.backgroundNode.frame = frame @@ -3627,6 +3629,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI strongSelf.backgroundWallpaperNode.updateFrame(frame, transition: .immediate) strongSelf.shadowNode.updateLayout(backgroundFrame: frame, transition: .immediate) } + }, completed: { [weak strongSelf] _ in + guard let strongSelf else { + return + } + strongSelf.clippingNode.clipsToBounds = false }) strongSelf.setAnimationForKey("backgroundNodeFrame", animation: backgroundAnimation) } else { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift index 2a10655502..4bf1ad17c1 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift @@ -236,8 +236,9 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco return false } if let item = self.item { - replyRecognizer.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply - self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + let _ = item + replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply } self.replyRecognizer = replyRecognizer self.view.addGestureRecognizer(replyRecognizer) @@ -646,8 +647,8 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco strongSelf.appliedCurrentlyPlaying = isPlaying strongSelf.appliedAutomaticDownload = automaticDownload - strongSelf.replyRecognizer?.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply - strongSelf.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + strongSelf.replyRecognizer?.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + strongSelf.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply strongSelf.updateAccessibilityData(accessibilityData) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift index 1711612045..2400e00a06 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift @@ -268,8 +268,9 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { return false } if let item = self.item { - replyRecognizer.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply - self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + let _ = item + replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply } self.replyRecognizer = replyRecognizer self.view.addGestureRecognizer(replyRecognizer) @@ -278,9 +279,9 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { override public func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) { super.setupItem(item, synchronousLoad: synchronousLoad) - self.replyRecognizer?.allowBothDirections = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.replyRecognizer?.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply if self.isNodeLoaded { - self.view.disablesInteractiveTransitionGestureRecognizer = !item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply + self.view.disablesInteractiveTransitionGestureRecognizer = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply } for media in item.message.media { diff --git a/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift b/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift index fb811c36ea..02832984ff 100644 --- a/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift +++ b/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift @@ -661,6 +661,7 @@ public final class MessageInlineBlockBackgroundView: UIView { } else { progressBackgroundContentsView = UIImageView() progressBackgroundContentsView.image = generateProgressTemplateImage() + self.progressBackgroundContentsView = progressBackgroundContentsView self.insertSubview(progressBackgroundContentsView, aboveSubview: self.backgroundView) progressBackgroundContentsView.tintColor = primaryColor } @@ -700,7 +701,9 @@ public final class MessageInlineBlockBackgroundView: UIView { if let progressBackgroundContentsView = self.progressBackgroundContentsView { self.progressBackgroundContentsView = nil let transition = ContainedViewLayoutTransition.animated(duration: 0.15, curve: .easeInOut) - transition.updateAlpha(layer: progressBackgroundContentsView.layer, alpha: 0.0) + transition.updateAlpha(layer: progressBackgroundContentsView.layer, alpha: 0.0, completion: { [weak progressBackgroundContentsView] _ in + progressBackgroundContentsView?.removeFromSuperview() + }) } self.progressBackgroundMaskContainer = nil self.progressBackgroundGradientView = nil diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift index b3602523f6..a91fa11935 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift @@ -168,91 +168,68 @@ private func chatForwardOptions(selfController: ChatControllerImpl, sourceNode: let hideCaptions = forwardOptions.hideCaptions if canHideNames { - items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in - if hideNames { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } + items.append(.action(ContextMenuActionItem(text: hideNames ? (uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames) : (uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames), icon: { theme in + return nil//generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] _, f in selfController?.interfaceInteraction?.updateForwardOptionsState({ current in var updated = current - updated.hideNames = false - updated.hideCaptions = false - updated.unhideNamesOnCaptionChange = false + if hideNames { + updated.hideNames = false + updated.hideCaptions = false + updated.unhideNamesOnCaptionChange = false + } else { + updated.hideNames = true + updated.unhideNamesOnCaptionChange = false + } return updated }) }))) - - items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames, icon: { theme in - if hideNames { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } else { - return nil - } - }, action: { [weak selfController] _, f in - selfController?.interfaceInteraction?.updateForwardOptionsState({ current in - var updated = current - updated.hideNames = true - updated.unhideNamesOnCaptionChange = false - return updated - }) - }))) - - items.append(.separator) } if hasCaptions { - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ShowCaption, icon: { theme in - if hideCaptions { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } + items.append(.action(ContextMenuActionItem(text: hideCaptions ? presentationData.strings.Conversation_ForwardOptions_ShowCaption : presentationData.strings.Conversation_ForwardOptions_HideCaption, icon: { theme in + return nil//generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] _, f in selfController?.interfaceInteraction?.updateForwardOptionsState({ current in var updated = current - updated.hideCaptions = false - if canHideNames { - if updated.unhideNamesOnCaptionChange { - updated.unhideNamesOnCaptionChange = false - updated.hideNames = false + if hideCaptions { + updated.hideCaptions = false + if canHideNames { + if updated.unhideNamesOnCaptionChange { + updated.unhideNamesOnCaptionChange = false + updated.hideNames = false + } + } + } else { + updated.hideCaptions = true + if canHideNames { + if !updated.hideNames { + updated.hideNames = true + updated.unhideNamesOnCaptionChange = true + } } } return updated }) }))) - - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_HideCaption, icon: { theme in - if hideCaptions { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } else { - return nil - } - }, action: { [weak selfController] _, f in - selfController?.interfaceInteraction?.updateForwardOptionsState({ current in - var updated = current - updated.hideCaptions = true - if canHideNames { - if !updated.hideNames { - updated.hideNames = true - updated.unhideNamesOnCaptionChange = true - } - } - return updated - }) - }))) - + } + + if !items.isEmpty { items.append(.separator) } - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ChangeRecipient, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ChangeRecipient, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replace"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in selfController?.interfaceInteraction?.forwardCurrentForwardMessages() f(.default) }))) - items.append(.action(ContextMenuActionItem(text: messagesCount == 1 ? presentationData.strings.Conversation_ForwardOptions_SendMessage : presentationData.strings.Conversation_ForwardOptions_SendMessages, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] c, f in + //TODO:localize + items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + f(.default) + }))) + + /*items.append(.action(ContextMenuActionItem(text: messagesCount == 1 ? presentationData.strings.Conversation_ForwardOptions_SendMessage : presentationData.strings.Conversation_ForwardOptions_SendMessages, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] c, f in guard let selfController else { return } @@ -265,10 +242,10 @@ private func chatForwardOptions(selfController: ChatControllerImpl, sourceNode: selfController.controllerInteraction?.sendCurrentMessage(false) f(.default) - }))) + })))*/ //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Remove Forward", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: "Do Not Forward", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -422,7 +399,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch } //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Reply in Another Chat", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: "Reply in Another Chat", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replace"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -434,6 +411,12 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch moveReplyMessageToAnotherChat(selfController: selfController, replySubject: replySubject) }))) + items.append(.separator) + + items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + f(.default) + }))) + if replySubject.quote != nil { items.append(.action(ContextMenuActionItem(text: "Remove Quote", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteRemove"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) @@ -446,7 +429,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(replySubject).withoutSelectionState() }).updatedSearch(nil) }) }))) } else { - items.append(.action(ContextMenuActionItem(text: "Remove Reply", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: "Do Not Reply", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -729,50 +712,21 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD if "".isEmpty { //TODO:localize - - items.append(.action(ContextMenuActionItem(text: "Above the Message", icon: { theme in - if linkOptions.linkBelowText { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } + items.append(.action(ContextMenuActionItem(text: linkOptions.linkBelowText ? "Move Up" : "Move Down", icon: { theme in + return nil//generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] _, f in selfController?.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in if state.interfaceState.editMessage != nil { guard var urlPreview = state.editingUrlPreview else { return state } - urlPreview.positionBelowText = false + urlPreview.positionBelowText = !urlPreview.positionBelowText return state.updatedEditingUrlPreview(urlPreview) } else { guard var urlPreview = state.urlPreview else { return state } - urlPreview.positionBelowText = false - return state.updatedUrlPreview(urlPreview) - } - }) - }))) - - items.append(.action(ContextMenuActionItem(text: "Below the Message", icon: { theme in - if !linkOptions.linkBelowText { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } - }, action: { [weak selfController] _, f in - selfController?.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in - if state.interfaceState.editMessage != nil { - guard var urlPreview = state.editingUrlPreview else { - return state - } - urlPreview.positionBelowText = true - return state.updatedEditingUrlPreview(urlPreview) - } else { - guard var urlPreview = state.urlPreview else { - return state - } - urlPreview.positionBelowText = true + urlPreview.positionBelowText = !urlPreview.positionBelowText return state.updatedUrlPreview(urlPreview) } }) @@ -780,55 +734,30 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD } if case let .Loaded(content) = linkOptions.webpage.content, let isMediaLargeByDefault = content.isMediaLargeByDefault, isMediaLargeByDefault { - if !items.isEmpty { - items.append(.separator) - } - //TODO:localize - - items.append(.action(ContextMenuActionItem(text: "Smaller Media", icon: { theme in - if linkOptions.largeMedia { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } + items.append(.action(ContextMenuActionItem(text: linkOptions.largeMedia ? "Shrink Photo" : "Enlarge Photo", icon: { theme in + return nil//generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] _, f in selfController?.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in if state.interfaceState.editMessage != nil { guard var urlPreview = state.editingUrlPreview else { return state } - urlPreview.largeMedia = false + if let largeMedia = urlPreview.largeMedia { + urlPreview.largeMedia = !largeMedia + } else { + urlPreview.largeMedia = false + } return state.updatedEditingUrlPreview(urlPreview) } else { guard var urlPreview = state.urlPreview else { return state } - urlPreview.largeMedia = false - return state.updatedUrlPreview(urlPreview) - } - }) - }))) - - items.append(.action(ContextMenuActionItem(text: "Larger Media", icon: { theme in - if !linkOptions.largeMedia { - return nil - } else { - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) - } - }, action: { [weak selfController] _, f in - selfController?.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in - if state.interfaceState.editMessage != nil { - guard var urlPreview = state.editingUrlPreview else { - return state + if let largeMedia = urlPreview.largeMedia { + urlPreview.largeMedia = !largeMedia + } else { + urlPreview.largeMedia = false } - urlPreview.largeMedia = true - return state.updatedEditingUrlPreview(urlPreview) - } else { - guard var urlPreview = state.urlPreview else { - return state - } - urlPreview.largeMedia = true return state.updatedUrlPreview(urlPreview) } }) @@ -840,7 +769,12 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD } //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Remove Link Preview", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController, weak chatController] c, f in + items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + f(.default) + }))) + + //TODO:localize + items.append(.action(ContextMenuActionItem(text: "Do Not Preview", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController, weak chatController] c, f in guard let selfController else { return } diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index c214d0cf93..cfe936e805 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -3920,7 +3920,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch let pasteboard = UIPasteboard.general var attributedString: NSAttributedString? - if let data = pasteboard.data(forPasteboardType: kUTTypeRTF as String) { + if let data = pasteboard.data(forPasteboardType: "private.telegramtext"), let value = chatInputStateStringFromAppSpecificString(data: data) { + attributedString = value + } else if let data = pasteboard.data(forPasteboardType: kUTTypeRTF as String) { attributedString = chatInputStateStringFromRTF(data, type: NSAttributedString.DocumentType.rtf) } else if let data = pasteboard.data(forPasteboardType: "com.apple.flat-rtfd") { attributedString = chatInputStateStringFromRTF(data, type: NSAttributedString.DocumentType.rtfd)