mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
10cae54a65
@ -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)
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user