[WIP] Quotes

This commit is contained in:
Ali 2023-10-14 00:41:44 +04:00
parent 679a10cbdf
commit ecb4e13969
24 changed files with 322 additions and 176 deletions

View File

@ -330,10 +330,10 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
updatedItems.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Back, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Back"), color: theme.contextMenu.primaryColor)
}, iconPosition: .left, action: { c, _ in
c.setItems(chatContextMenuItems(context: context, peerId: peerId, promoInfo: promoInfo, source: source, chatListController: chatListController, joined: joined) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(chatContextMenuItems(context: context, peerId: peerId, promoInfo: promoInfo, source: source, chatListController: chatListController, joined: joined) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
c.setItems(.single(ContextController.Items(content: .list(updatedItems))), minHeight: nil)
c.setItems(.single(ContextController.Items(content: .list(updatedItems))), minHeight: nil, animated: true)
})))
}
}
@ -658,7 +658,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
})))
//c.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
c.setItems(.single(ContextController.Items(content: .list(subItems))), minHeight: nil)
c.setItems(.single(ContextController.Items(content: .list(subItems))), minHeight: nil, animated: true)
})))
items.append(.separator)
@ -813,7 +813,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
c.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil)
c.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil, animated: true)
}
})))

View File

@ -24,7 +24,7 @@ public protocol ContextControllerProtocol: ViewController {
func dismiss(completion: (() -> Void)?)
func getActionsMinHeight() -> ContextController.ActionsHeight?
func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?)
func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, animated: Bool)
func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, previousActionsTransition: ContextController.PreviousActionsTransition)
func pushItems(items: Signal<ContextController.Items, NoError>)
func popItems()
@ -1326,9 +1326,9 @@ final class ContextControllerNode: ViewControllerTracingNode, UIScrollViewDelega
}
}
func setItemsSignal(items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, previousActionsTransition: ContextController.PreviousActionsTransition) {
func setItemsSignal(items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, previousActionsTransition: ContextController.PreviousActionsTransition, animated: Bool) {
if let sourceContainer = self.sourceContainer {
sourceContainer.setItems(items: items, animated: false)
sourceContainer.setItems(items: items, animated: animated)
} else {
self.legacyItems = items
self.itemsDisposable.set((items
@ -2555,12 +2555,12 @@ public final class ContextController: ViewController, StandalonePresentableContr
return nil
}
public func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?) {
public func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, animated: Bool) {
//self.items = items
if self.isNodeLoaded {
self.immediateItemsTransitionAnimation = false
self.controllerNode.setItemsSignal(items: items, minHeight: minHeight, previousActionsTransition: .scale)
self.controllerNode.setItemsSignal(items: items, minHeight: minHeight, previousActionsTransition: .scale, animated: animated)
} else {
assertionFailure()
}
@ -2570,7 +2570,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
//self.items = items
if self.isNodeLoaded {
self.controllerNode.setItemsSignal(items: items, minHeight: minHeight, previousActionsTransition: previousActionsTransition)
self.controllerNode.setItemsSignal(items: items, minHeight: minHeight, previousActionsTransition: previousActionsTransition, animated: true)
} else {
assertionFailure()
}

View File

@ -234,7 +234,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
private let requestAnimateOut: (ContextMenuActionResult, @escaping () -> Void) -> Void
private let source: ContentSource
private let backgroundNode: NavigationBackgroundNode
private let dismissTapNode: ASDisplayNode
private let dismissAccessibilityArea: AccessibilityAreaNode
private let clippingNode: ASDisplayNode
@ -282,8 +281,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
self.requestAnimateOut = requestAnimateOut
self.source = source
self.backgroundNode = NavigationBackgroundNode(color: .clear, enableBlur: false)
self.dismissTapNode = ASDisplayNode()
self.dismissAccessibilityArea = AccessibilityAreaNode()
@ -330,7 +327,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
self.view.addSubview(self.scroller)
self.scroller.isHidden = true
self.addSubnode(self.backgroundNode)
self.addSubnode(self.clippingNode)
self.clippingNode.addSubnode(self.scrollNode)
self.scrollNode.addSubnode(self.dismissTapNode)
@ -553,7 +549,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
) {
self.validLayout = layout
let contentActionsSpacing: CGFloat = 7.0
var contentActionsSpacing: CGFloat = 7.0
let actionsEdgeInset: CGFloat
let actionsSideInset: CGFloat
let topInset: CGFloat = layout.insets(options: .statusBar).top + 8.0
@ -571,37 +567,17 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
switch self.source {
case .location, .reference:
self.backgroundNode.updateColor(
color: .clear,
enableBlur: false,
forceKeepBlur: false,
transition: .immediate
)
actionsEdgeInset = 16.0
actionsSideInset = 6.0
case .extracted:
self.backgroundNode.updateColor(
color: presentationData.theme.contextMenu.dimColor,
enableBlur: true,
forceKeepBlur: true,
transition: .immediate
)
actionsEdgeInset = 12.0
actionsSideInset = 6.0
case .controller:
self.backgroundNode.updateColor(
color: presentationData.theme.contextMenu.dimColor,
enableBlur: true,
forceKeepBlur: true,
transition: .immediate
)
actionsEdgeInset = 12.0
actionsSideInset = -2.0
contentActionsSpacing += 3.0
}
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
self.backgroundNode.update(size: layout.size, transition: transition)
transition.updateFrame(node: self.clippingNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
if self.scrollNode.frame != CGRect(origin: CGPoint(), size: layout.size) {
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
@ -1085,8 +1061,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
self.scroller.contentOffset = CGPoint(x: 0.0, y: defaultScrollY)
self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let animationInContentYDistance: CGFloat
let currentContentScreenFrame: CGRect
if let contentNode = itemContentNode {
@ -1473,8 +1447,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
additive: true
)
self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false)
if let reactionContextNode = self.reactionContextNode {
reactionContextNode.animateOut(to: currentContentScreenFrame, animatingOutToReaction: self.reactionContextNodeIsAnimatingOut)
}

View File

@ -335,6 +335,8 @@ final class ContextSourceContainer: ASDisplayNode {
private weak var controller: ContextController?
private let backgroundNode: NavigationBackgroundNode
var sources: [Source] = []
var activeIndex: Int = 0
@ -360,8 +362,12 @@ final class ContextSourceContainer: ASDisplayNode {
init(controller: ContextController, configuration: ContextController.Configuration) {
self.controller = controller
self.backgroundNode = NavigationBackgroundNode(color: .clear, enableBlur: false)
super.init()
self.addSubnode(self.backgroundNode)
for i in 0 ..< configuration.sources.count {
let source = configuration.sources[i]
@ -443,6 +449,8 @@ final class ContextSourceContainer: ASDisplayNode {
}
func animateIn() {
self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
if let activeSource = self.activeSource {
activeSource.animateIn()
}
@ -452,6 +460,8 @@ final class ContextSourceContainer: ASDisplayNode {
}
func animateOut(result: ContextMenuActionResult, completion: @escaping () -> Void) {
self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
if let tabSelectorView = self.tabSelector?.view {
tabSelectorView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
}
@ -543,6 +553,35 @@ final class ContextSourceContainer: ASDisplayNode {
var childLayout = layout
if let activeSource = self.activeSource {
switch activeSource.source {
case .location, .reference:
self.backgroundNode.updateColor(
color: .clear,
enableBlur: false,
forceKeepBlur: false,
transition: .immediate
)
case .extracted:
self.backgroundNode.updateColor(
color: presentationData.theme.contextMenu.dimColor,
enableBlur: true,
forceKeepBlur: true,
transition: .immediate
)
case .controller:
self.backgroundNode.updateColor(
color: presentationData.theme.contextMenu.dimColor,
enableBlur: true,
forceKeepBlur: true,
transition: .immediate
)
}
}
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
self.backgroundNode.update(size: layout.size, transition: transition)
if self.sources.count > 1 {
let tabSelector: ComponentView<Empty>
if let current = self.tabSelector {
@ -561,6 +600,9 @@ final class ContextSourceContainer: ASDisplayNode {
foreground: presentationData.theme.contextMenu.primaryColor.withMultipliedAlpha(0.8),
selection: presentationData.theme.contextMenu.primaryColor.withMultipliedAlpha(0.1)
),
customLayout: TabSelectorComponent.CustomLayout(
spacing: 9.0
),
items: mappedItems,
selectedId: self.activeSource?.id,
setSelectedId: { [weak self] id in
@ -576,7 +618,7 @@ final class ContextSourceContainer: ASDisplayNode {
environment: {},
containerSize: CGSize(width: layout.size.width, height: 44.0)
)
childLayout.intrinsicInsets.bottom += 44.0
childLayout.intrinsicInsets.bottom += 30.0
if let tabSelectorView = tabSelector.view {
if tabSelectorView.superview == nil {

View File

@ -38,7 +38,7 @@ public final class PeekController: ViewController, ContextControllerProtocol {
return nil
}
public func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?) {
public func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, animated: Bool) {
}
public func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, previousActionsTransition: ContextController.PreviousActionsTransition) {

View File

@ -2505,7 +2505,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
return
}
c.setItems(strongSelf.contextMenuSpeedItems(dismiss: dismiss) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuSpeedItems(dismiss: dismiss) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
items.append(.separator)
@ -2634,7 +2634,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
c.dismiss(completion: nil)
return
}
c.setItems(strongSelf.contextMenuMainItems(dismiss: dismiss) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuMainItems(dismiss: dismiss) |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
let sliderValuePromise = ValuePromise<Double?>(nil)

View File

@ -2517,7 +2517,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuDisplayAsItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuDisplayAsItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
items.append(.separator)
break
@ -2550,7 +2550,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuAudioItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuAudioItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
}
@ -2587,7 +2587,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuPermissionItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuPermissionItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
}
}
@ -2865,7 +2865,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
return .single(items)
}
@ -2960,7 +2960,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
return items
}
@ -3006,7 +3006,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
guard let strongSelf = self else {
return
}
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(strongSelf.contextMenuMainItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
})))
}
return .single(items)

View File

@ -6,7 +6,7 @@ import TelegramPresentationData
import ChatPresentationInterfaceState
import ShimmerEffect
private let buttonFont = Font.semibold(13.0)
private let buttonFont = Font.semibold(14.0)
public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
private let textNode: TextNode
@ -107,7 +107,7 @@ public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButton
})
}
public static func asyncLayout(_ current: ChatMessageAttachedContentButtonNode?) -> (_ width: CGFloat, _ regularImage: UIImage, _ highlightedImage: UIImage, _ iconImage: UIImage?, _ highlightedIconImage: UIImage?, _ cornerIcon: Bool, _ title: String, _ titleColor: UIColor, _ highlightedTitleColor: UIColor, _ inProgress: Bool) -> (CGFloat, (CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode)) {
public static func asyncLayout(_ current: ChatMessageAttachedContentButtonNode?) -> (_ width: CGFloat, _ regularImage: UIImage?, _ highlightedImage: UIImage?, _ iconImage: UIImage?, _ highlightedIconImage: UIImage?, _ cornerIcon: Bool, _ title: String, _ titleColor: UIColor, _ highlightedTitleColor: UIColor, _ inProgress: Bool) -> (CGFloat, (CGFloat, CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode)) {
let previousRegularImage = current?.regularImage
let previousHighlightedImage = current?.highlightedImage
let previousRegularIconImage = current?.regularIconImage
@ -169,10 +169,14 @@ public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButton
let (_, highlightedTextApply) = makeHighlightedTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: buttonFont, textColor: highlightedTitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, width - labelInset * 2.0), height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets()))
return (textSize.size.width + labelInset * 2.0, { refinedWidth in
return (CGSize(width: refinedWidth, height: 33.0), {
return (textSize.size.width + labelInset * 2.0, { refinedWidth, refinedHeight in
let size = CGSize(width: refinedWidth, height: refinedHeight)
return (size, {
targetNode.accessibilityLabel = title
//targetNode.borderColor = UIColor.red.cgColor
//targetNode.borderWidth = 1.0
targetNode.titleColor = titleColor
if let updatedRegularImage = updatedRegularImage {
@ -203,15 +207,15 @@ public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButton
let _ = textApply()
let _ = highlightedTextApply()
let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: refinedWidth, height: 33.0))
var textFrame = CGRect(origin: CGPoint(x: floor((refinedWidth - textSize.size.width) / 2.0), y: floor((34.0 - textSize.size.height) / 2.0)), size: textSize.size)
let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: refinedWidth, height: size.height))
var textFrame = CGRect(origin: CGPoint(x: floor((refinedWidth - textSize.size.width) / 2.0), y: floor((backgroundFrame.height - textSize.size.height) / 2.0)), size: textSize.size)
targetNode.backgroundNode.frame = backgroundFrame
if let image = targetNode.iconNode.image {
if cornerIcon {
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: backgroundFrame.maxX - image.size.width - 5.0, y: 5.0), size: image.size)
} else {
textFrame.origin.x += floor(image.size.width / 2.0)
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: textFrame.minX - image.size.width - 5.0, y: textFrame.minY + 2.0), size: image.size)
targetNode.iconNode.frame = CGRect(origin: CGPoint(x: textFrame.minX - image.size.width - 5.0, y: textFrame.minY + floorToScreenPixels((textFrame.height - image.size.height) * 0.5)), size: image.size)
}
if targetNode.iconNode.supernode == nil {
targetNode.addSubnode(targetNode.iconNode)

View File

@ -51,7 +51,7 @@ public struct ChatMessageAttachedContentNodeMediaFlags: OptionSet {
public static let titleBeforeMedia = ChatMessageAttachedContentNodeMediaFlags(rawValue: 1 << 3)
}
public final class ChatMessageAttachedContentNode: ASDisplayNode {
public final class ChatMessageAttachedContentNode: HighlightTrackingButtonNode {
private var backgroundView: UIImageView?
private let topTitleNode: TextNode
private let textNode: TextNodeWithEntities
@ -60,6 +60,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
private var contentInstantVideoNode: ChatMessageInteractiveInstantVideoNode?
private var contentFileNode: ChatMessageInteractiveFileNode?
private var buttonNode: ChatMessageAttachedContentButtonNode?
private var buttonSeparatorLayer: SimpleLayer?
public let statusNode: ChatMessageDateAndStatusNode
private var additionalImageBadgeNode: ChatMessageInteractiveMediaBadge?
@ -93,7 +94,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
}
override public init() {
public init() {
self.topTitleNode = TextNode()
self.topTitleNode.isUserInteractionEnabled = false
self.topTitleNode.displaysAsynchronously = false
@ -108,17 +109,35 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
self.inlineImageNode = TransformImageNode()
self.inlineImageNode.contentAnimations = [.subsequentUpdates]
self.inlineImageNode.isLayerBacked = !smartInvertColorsEnabled()
self.inlineImageNode.isLayerBacked = false
self.inlineImageNode.displaysAsynchronously = false
self.statusNode = ChatMessageDateAndStatusNode()
super.init()
super.init(pointerStyle: .default)
self.addSubnode(self.topTitleNode)
self.addSubnode(self.textNode.textNode)
self.addSubnode(self.statusNode)
self.highligthedChanged = { [weak self] highlighted in
guard let self else {
return
}
if self.bounds.width < 1.0 {
return
}
let transition: ContainedViewLayoutTransition = .animated(duration: highlighted ? 0.1 : 0.2, curve: .easeInOut)
let scale: CGFloat = highlighted ? ((self.bounds.width - 10.0) / self.bounds.width) : 1.0
transition.updateSublayerTransformScale(node: self, scale: scale)
}
self.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
}
@objc private func pressed() {
self.activateAction?()
}
public func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ context: AccountContext, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ chatLocation: ChatLocation, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ constrainedSize: CGSize, _ animationCache: AnimationCache, _ animationRenderer: MultiAnimationRenderer) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
@ -142,7 +161,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
if message.adAttribute != nil {
fontSize = floor(presentationData.fontSize.baseDisplaySize)
} else {
fontSize = floor(presentationData.fontSize.baseDisplaySize * 15.0 / 17.0)
fontSize = floor(presentationData.fontSize.baseDisplaySize * 14.0 / 17.0)
}
let titleFont = Font.semibold(fontSize)
@ -160,8 +179,8 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
var horizontalInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
if displayLine {
horizontalInsets.left += 12.0
horizontalInsets.right += 12.0
horizontalInsets.left += 10.0
horizontalInsets.right += 9.0
}
var titleBeforeMedia = false
@ -509,7 +528,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
if let _ = inlineImageDimensions {
inlineImageSize = CGSize(width: 54.0, height: 54.0)
inlineImageSize = CGSize(width: 53.0, height: 53.0)
if let inlineImageSize = inlineImageSize {
textCutout.topRight = CGSize(width: inlineImageSize.width + 10.0, height: inlineImageSize.height + 10.0)
@ -517,19 +536,24 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
return (initialWidth, { constrainedSize, position in
var insets = UIEdgeInsets(top: 0.0, left: horizontalInsets.left, bottom: 5.0, right: horizontalInsets.right)
var lineInsets = insets
//insets.top += 4.0
//insets.bottom += 4.0
var insets = UIEdgeInsets(top: 0.0, left: horizontalInsets.left, bottom: 0.0, right: horizontalInsets.right)
switch position {
case .linear(.None, _):
case let .linear(topNeighbor, bottomNeighbor):
switch topNeighbor {
case .None:
insets.top += 10.0
insets.bottom += 8.0
lineInsets.top += 10.0 + 8.0
default:
break
}
switch bottomNeighbor {
case .None:
insets.bottom += 12.0
default:
insets.bottom += 0.0
}
default:
break
}
let textConstrainedSize = CGSize(width: constrainedSize.width - insets.left - insets.right, height: constrainedSize.height - insets.top - insets.bottom)
@ -614,9 +638,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
var boundingSize = textFrame.size
var lineHeight = textLayout.rawTextSize.height
if titleBeforeMedia {
lineHeight += topTitleLayout.size.height + 4.0
boundingSize.height += topTitleLayout.size.height + 4.0
boundingSize.width = max(boundingSize.width, topTitleLayout.size.width)
}
@ -624,9 +646,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
if boundingSize.height < inlineImageSize.height {
boundingSize.height = inlineImageSize.height
}
if lineHeight < inlineImageSize.height {
lineHeight = inlineImageSize.height
}
}
if let statusSuggestedWidthAndContinue = statusSuggestedWidthAndContinue {
@ -652,8 +671,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
boundingSize.width = max(boundingSize.width, videoLayout.contentSize.width + videoLayout.overflowLeft + videoLayout.overflowRight)
}
lineHeight += lineInsets.top + lineInsets.bottom
var imageApply: (() -> Void)?
if let inlineImageSize = inlineImageSize, let inlineImageDimensions = inlineImageDimensions {
let imageCorners = ImageCorners(topLeft: .Corner(4.0), topRight: .Corner(4.0), bottomLeft: .Corner(4.0), bottomRight: .Corner(4.0))
@ -661,18 +678,14 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
imageApply = imageLayout(arguments)
}
var continueActionButtonLayout: ((CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode))?
var continueActionButtonLayout: ((CGFloat, CGFloat) -> (CGSize, () -> ChatMessageAttachedContentButtonNode))?
if let actionTitle = actionTitle, !isPreview {
let buttonImage: UIImage
let buttonHighlightedImage: UIImage
var buttonIconImage: UIImage?
var buttonHighlightedIconImage: UIImage?
var cornerIcon = false
let titleColor: UIColor
let titleHighlightedColor: UIColor
if incoming {
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonIncoming(presentationData.theme.theme)!
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonIncoming(presentationData.theme.theme)!
if let actionIcon {
switch actionIcon {
case .instant:
@ -688,8 +701,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: true, wallpaper: !presentationData.theme.wallpaper.isEmpty)
titleHighlightedColor = bubbleColor.fill[0]
} else {
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(presentationData.theme.theme)!
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonOutgoing(presentationData.theme.theme)!
if let actionIcon {
switch actionIcon {
case .instant:
@ -705,7 +716,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
let bubbleColor = bubbleColorComponents(theme: presentationData.theme.theme, incoming: false, wallpaper: !presentationData.theme.wallpaper.isEmpty)
titleHighlightedColor = bubbleColor.fill[0]
}
let (buttonWidth, continueLayout) = makeButtonLayout(constrainedSize.width, buttonImage, buttonHighlightedImage, buttonIconImage, buttonHighlightedIconImage, cornerIcon, actionTitle, titleColor, titleHighlightedColor, false)
let (buttonWidth, continueLayout) = makeButtonLayout(constrainedSize.width, nil, nil, buttonIconImage, buttonHighlightedIconImage, cornerIcon, actionTitle, titleColor, titleHighlightedColor, false)
boundingSize.width = max(buttonWidth, boundingSize.width)
continueActionButtonLayout = continueLayout
}
@ -715,11 +726,10 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
return (boundingSize.width, { boundingWidth in
var adjustedBoundingSize = boundingSize
var adjustedLineHeight = lineHeight
var imageFrame: CGRect?
if let inlineImageSize = inlineImageSize {
imageFrame = CGRect(origin: CGPoint(x: boundingWidth - inlineImageSize.width - insets.right, y: 0.0), size: inlineImageSize)
imageFrame = CGRect(origin: CGPoint(x: boundingWidth - inlineImageSize.width - insets.right + 4.0, y: 0.0), size: inlineImageSize)
}
var contentImageSizeAndApply: (CGSize, (ListViewItemUpdateAnimation, Bool) -> ChatMessageInteractiveMediaNode)?
@ -732,8 +742,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
imageHeightAddition += 2.0
}
adjustedBoundingSize.height += imageHeightAddition + 5.0
adjustedLineHeight += imageHeightAddition + 4.0
adjustedBoundingSize.height += imageHeightAddition + 7.0
}
var contentFileSizeAndApply: (CGSize, (Bool, ListViewItemUpdateAnimation, ListViewItemApply?) -> ChatMessageInteractiveFileNode)?
@ -749,25 +758,26 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
adjustedBoundingSize.height += imageHeightAddition + 5.0
adjustedLineHeight += imageHeightAddition + 4.0
}
if let (videoLayout, _) = contentInstantVideoSizeAndApply {
let imageHeightAddition = videoLayout.contentSize.height + 6.0
if textFrame.size.height > CGFloat.ulpOfOne {
//imageHeightAddition += 2.0
}
adjustedBoundingSize.height += imageHeightAddition// + 5.0
adjustedLineHeight += imageHeightAddition// + 4.0
}
var actionButtonSizeAndApply: ((CGSize, () -> ChatMessageAttachedContentButtonNode))?
if let continueActionButtonLayout = continueActionButtonLayout {
let (size, apply) = continueActionButtonLayout(boundingWidth - 12.0 - insets.right)
let (size, apply) = continueActionButtonLayout(boundingWidth - 5.0 - insets.right, 38.0)
actionButtonSizeAndApply = (size, apply)
adjustedBoundingSize.width = max(adjustedBoundingSize.width, insets.left + size.width + insets.right)
adjustedBoundingSize.height += 7.0 + size.height
adjustedBoundingSize.height += 4.0 + size.height
if let text, !text.isEmpty {
if contentImageSizeAndApply == nil {
adjustedBoundingSize.height += 5.0
} else if let (_, flags) = mediaAndFlags, flags.contains(.preferMediaBeforeText) {
adjustedBoundingSize.height += 5.0
}
}
}
var statusSizeAndApply: ((CGSize), (ListViewItemUpdateAnimation) -> Void)?
@ -776,7 +786,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
if let statusSizeAndApply = statusSizeAndApply {
adjustedBoundingSize.height += statusSizeAndApply.0.height
adjustedLineHeight += statusSizeAndApply.0.height
if let imageFrame = imageFrame, statusSizeAndApply.0.height == 0.0 {
if statusInText {
@ -819,7 +828,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
finalStatusFrame.origin.y += 14.0
adjustedBoundingSize.height += 14.0
adjustedLineHeight += 14.0
}
}
}
@ -847,9 +855,12 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
}
backgroundView.tintColor = mainColor
animation.animator.updateFrame(layer: backgroundView.layer, frame: CGRect(origin: CGPoint(x: 11.0, y: insets.top), size: CGSize(width: adjustedBoundingSize.width - 1.0 - insets.right, height: adjustedLineHeight - insets.top - insets.bottom - 2.0)), completion: nil)
animation.animator.updateFrame(layer: backgroundView.layer, frame: CGRect(origin: CGPoint(x: 11.0, y: insets.top - 3.0), size: CGSize(width: adjustedBoundingSize.width - 4.0 - insets.right, height: adjustedBoundingSize.height - insets.top - insets.bottom + 4.0)), completion: nil)
backgroundView.isHidden = !displayLine
//strongSelf.borderColor = UIColor.red.cgColor
//strongSelf.borderWidth = 2.0
strongSelf.textNode.textNode.displaysAsynchronously = !isPreview
let _ = topTitleApply()
@ -1003,20 +1014,47 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
if let (size, apply) = actionButtonSizeAndApply {
let buttonNode = apply()
let buttonFrame = CGRect(origin: CGPoint(x: 12.0, y: adjustedBoundingSize.height - insets.bottom - size.height), size: size)
if buttonNode !== strongSelf.buttonNode {
strongSelf.buttonNode?.removeFromSupernode()
strongSelf.buttonNode = buttonNode
buttonNode.isUserInteractionEnabled = false
strongSelf.addSubnode(buttonNode)
buttonNode.pressed = {
if let strongSelf = self {
strongSelf.activateAction?()
}
}
buttonNode.frame = buttonFrame
} else {
animation.animator.updateFrame(layer: buttonNode.layer, frame: buttonFrame, completion: nil)
}
let buttonSeparatorFrame = CGRect(origin: CGPoint(x: buttonFrame.minX + 8.0, y: buttonFrame.minY - 2.0), size: CGSize(width: buttonFrame.width - 8.0 - 8.0, height: UIScreenPixel))
let buttonSeparatorLayer: SimpleLayer
if let current = strongSelf.buttonSeparatorLayer {
buttonSeparatorLayer = current
animation.animator.updateFrame(layer: buttonSeparatorLayer, frame: buttonSeparatorFrame, completion: nil)
} else {
buttonSeparatorLayer = SimpleLayer()
strongSelf.buttonSeparatorLayer = buttonSeparatorLayer
strongSelf.layer.addSublayer(buttonSeparatorLayer)
buttonSeparatorLayer.frame = buttonSeparatorFrame
}
buttonSeparatorLayer.backgroundColor = mainColor.withMultipliedAlpha(0.5).cgColor
} else {
if let buttonNode = strongSelf.buttonNode {
strongSelf.buttonNode = nil
buttonNode.removeFromSupernode()
}
if let buttonSeparatorLayer = strongSelf.buttonSeparatorLayer {
strongSelf.buttonSeparatorLayer = nil
buttonSeparatorLayer.removeFromSuperlayer()
}
buttonNode.frame = CGRect(origin: CGPoint(x: 12.0, y: adjustedLineHeight - insets.top - insets.bottom - 2.0 + 6.0), size: size)
} else if let buttonNode = strongSelf.buttonNode {
buttonNode.removeFromSupernode()
strongSelf.buttonNode = nil
}
}
})
@ -1090,10 +1128,10 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
} else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag {
return .hashtag(hashtag.peerName, hashtag.hashtag)
} else {
return .none
return .ignore
}
} else {
return .none
return .ignore
}
}

View File

@ -69,6 +69,9 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
private var textSelectionState: Promise<ChatControllerSubject.MessageOptionsInfo.SelectionState>?
private var linkPreviewOptionsDisposable: Disposable?
private var linkPreviewHighlightingNodes: [LinkHighlightingNode] = []
override public var visibility: ListViewItemNodeVisibility {
didSet {
if oldValue != self.visibility {
@ -128,6 +131,10 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.linkPreviewOptionsDisposable?.dispose()
}
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
let textLayout = TextNodeWithEntities.asyncLayout(self.textNode)
let spoilerTextLayout = TextNodeWithEntities.asyncLayout(self.spoilerTextNode)
@ -566,27 +573,40 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
strongSelf.statusNode.pressed = nil
}
if let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject, case let .reply(info) = info {
if strongSelf.textSelectionNode == nil {
strongSelf.updateIsExtractedToContextPreview(true)
if let initialQuote = info.quote, item.message.id == initialQuote.messageId, let string = strongSelf.textNode.textNode.cachedLayout?.attributedString {
let nsString = string.string as NSString
let subRange = nsString.range(of: initialQuote.text)
if subRange.location != NSNotFound {
strongSelf.beginTextSelection(range: subRange, displayMenu: false)
if let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject {
if case let .reply(info) = info {
if strongSelf.textSelectionNode == nil {
strongSelf.updateIsExtractedToContextPreview(true)
if let initialQuote = info.quote, item.message.id == initialQuote.messageId, let string = strongSelf.textNode.textNode.cachedLayout?.attributedString {
let nsString = string.string as NSString
let subRange = nsString.range(of: initialQuote.text)
if subRange.location != NSNotFound {
strongSelf.beginTextSelection(range: subRange, displayMenu: false)
}
}
if strongSelf.textSelectionState == nil {
if let textSelectionNode = strongSelf.textSelectionNode {
let range = textSelectionNode.getSelection()
strongSelf.textSelectionState = Promise(strongSelf.getSelectionState(range: range))
} else {
strongSelf.textSelectionState = Promise(strongSelf.getSelectionState(range: nil))
}
}
if let textSelectionState = strongSelf.textSelectionState {
info.selectionState.set(textSelectionState.get())
}
}
if strongSelf.textSelectionState == nil {
if let textSelectionNode = strongSelf.textSelectionNode {
let range = textSelectionNode.getSelection()
strongSelf.textSelectionState = Promise(strongSelf.getSelectionState(range: range))
} else {
strongSelf.textSelectionState = Promise(strongSelf.getSelectionState(range: nil))
}
}
if let textSelectionState = strongSelf.textSelectionState {
info.selectionState.set(textSelectionState.get())
} else if case let .link(link) = info {
if strongSelf.linkPreviewOptionsDisposable == nil {
strongSelf.linkPreviewOptionsDisposable = (link.options
|> deliverOnMainQueue).startStrict(next: { [weak strongSelf] options in
guard let strongSelf else {
return
}
strongSelf.updateLinkPreviewTextHighlightState(text: options.url)
})
}
}
}
@ -613,6 +633,13 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
if case .tap = gesture {
} else {
if let item = self.item, let subject = item.associatedData.subject, case .messageOptions = subject {
return .none
}
}
let textNodeFrame = self.textNode.textNode.frame
if let (index, attributes) = self.textNode.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) {
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Spoiler)], !(self.dustNode?.isRevealed ?? true) {
@ -764,7 +791,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
for i in 0 ..< rectsSet.count {
let rects = rectsSet[i]
let textHighlightNode: LinkHighlightingNode
if self.textHighlightingNodes.count < i {
if i < self.textHighlightingNodes.count {
textHighlightNode = self.textHighlightingNodes[i]
} else {
textHighlightNode = LinkHighlightingNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.textHighlightColor : item.presentationData.theme.theme.chat.message.outgoing.textHighlightColor)
@ -780,6 +807,39 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
}
private func updateLinkPreviewTextHighlightState(text: String?) {
guard let item = self.item else {
return
}
var rectsSet: [[CGRect]] = []
if let text = text, !text.isEmpty, let cachedLayout = self.textNode.textNode.cachedLayout, let string = cachedLayout.attributedString?.string {
let nsString = string as NSString
let range = nsString.range(of: text)
if range.location != NSNotFound {
if let rects = cachedLayout.rangeRects(in: range)?.rects, !rects.isEmpty {
rectsSet = [rects]
}
}
}
for i in 0 ..< rectsSet.count {
let rects = rectsSet[i]
let textHighlightNode: LinkHighlightingNode
if i < self.linkPreviewHighlightingNodes.count {
textHighlightNode = self.linkPreviewHighlightingNodes[i]
} else {
textHighlightNode = LinkHighlightingNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.linkHighlightColor : item.presentationData.theme.theme.chat.message.outgoing.linkHighlightColor)
self.linkPreviewHighlightingNodes.append(textHighlightNode)
self.insertSubnode(textHighlightNode, belowSubnode: self.textNode.textNode)
}
textHighlightNode.frame = self.textNode.textNode.frame
textHighlightNode.updateRects(rects)
}
for i in (rectsSet.count ..< self.linkPreviewHighlightingNodes.count).reversed() {
self.linkPreviewHighlightingNodes[i].removeFromSupernode()
self.linkPreviewHighlightingNodes.remove(at: i)
}
}
override public func willUpdateIsExtractedToContextPreview(_ value: Bool) {
if !value {
if let textSelectionNode = self.textSelectionNode {

View File

@ -24,7 +24,7 @@ private let titleFont: UIFont = Font.semibold(15.0)
public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
private var webPage: TelegramMediaWebpage?
private let contentNode: ChatMessageAttachedContentNode
private var contentNode: ChatMessageAttachedContentNode
override public var visibility: ListViewItemNodeVisibility {
didSet {
@ -83,6 +83,8 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
if let webpage = webPageContent {
if webpage.story != nil {
let _ = item.controllerInteraction.openMessage(item.message, .default)
} else if webpage.instantPage != nil {
strongSelf.contentNode.openMedia?(.default)
} else {
item.controllerInteraction.openUrl(webpage.url, false, nil, nil)
}
@ -351,10 +353,12 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
}
}
if webpage.displayOptions.largeMedia == false {
mediaAndFlags?.1.insert(.preferMediaInline)
} else {
mediaAndFlags?.1.remove(.preferMediaInline)
if let largeMedia = webpage.displayOptions.largeMedia {
if largeMedia {
mediaAndFlags?.1.remove(.preferMediaInline)
} else {
mediaAndFlags?.1.insert(.preferMediaInline)
}
}
} else if let adAttribute = item.message.adAttribute {
title = nil

View File

@ -18,6 +18,14 @@ public final class TabSelectorComponent: Component {
}
}
public struct CustomLayout: Equatable {
public var spacing: CGFloat
public init(spacing: CGFloat) {
self.spacing = spacing
}
}
public struct Item: Equatable {
public var id: AnyHashable
public var title: String
@ -32,17 +40,20 @@ public final class TabSelectorComponent: Component {
}
public let colors: Colors
public let customLayout: CustomLayout?
public let items: [Item]
public let selectedId: AnyHashable?
public let setSelectedId: (AnyHashable) -> Void
public init(
colors: Colors,
customLayout: CustomLayout? = nil,
items: [Item],
selectedId: AnyHashable?,
setSelectedId: @escaping (AnyHashable) -> Void
) {
self.colors = colors
self.customLayout = customLayout
self.items = items
self.selectedId = selectedId
self.setSelectedId = setSelectedId
@ -52,6 +63,9 @@ public final class TabSelectorComponent: Component {
if lhs.colors != rhs.colors {
return false
}
if lhs.customLayout != rhs.customLayout {
return false
}
if lhs.items != rhs.items {
return false
}
@ -96,7 +110,14 @@ public final class TabSelectorComponent: Component {
let baseHeight: CGFloat = 28.0
let innerInset: CGFloat = 12.0
let spacing: CGFloat = 2.0
let spacing: CGFloat = component.customLayout?.spacing ?? 2.0
let itemFont: UIFont
if component.customLayout != nil {
itemFont = Font.medium(14.0)
} else {
itemFont = Font.semibold(14.0)
}
if self.selectionView.image == nil {
self.selectionView.image = generateStretchableFilledCircleImage(diameter: baseHeight, color: component.colors.selection)
@ -123,7 +144,7 @@ public final class TabSelectorComponent: Component {
let itemSize = itemView.title.update(
transition: .immediate,
component: AnyComponent(PlainButtonComponent(
content: AnyComponent(Text(text: item.title, font: Font.semibold(14.0), color: component.colors.foreground)),
content: AnyComponent(Text(text: item.title, font: itemFont, color: component.colors.foreground)),
effectAlignment: .center,
minSize: nil,
action: { [weak self] in

View File

@ -1,22 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ConversationInstantPageButtonIconIncoming@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ConversationInstantPageButtonIconIncoming@3x.png",
"scale" : "3x"
"filename" : "InstantIcon.svg",
"idiom" : "universal"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@ -0,0 +1,3 @@
<svg width="11" height="16" viewBox="0 0 11 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.07593 6.66558C6.74821 6.66558 6.49801 6.37278 6.54912 6.04906L7.26175 1.53576C7.35044 0.974067 6.61589 0.682105 6.29478 1.15142L1.26837 8.4977C1.02619 8.85167 1.27965 9.3322 1.70854 9.3322H3.91886C4.24658 9.3322 4.49678 9.625 4.44567 9.94871L3.73304 14.462C3.64435 15.0237 4.3789 15.3157 4.70001 14.8464L9.72642 7.50008C9.9686 7.14611 9.71514 6.66558 9.28625 6.66558H7.07593Z" fill="#3CA5EC"/>
</svg>

After

Width:  |  Height:  |  Size: 549 B

View File

@ -27,6 +27,12 @@ private func presentChatInputOptions(selfController: ChatControllerImpl, sourceN
let replySelectionState = Promise<ChatControllerSubject.MessageOptionsInfo.SelectionState>(ChatControllerSubject.MessageOptionsInfo.SelectionState(quote: nil))
if let source = chatReplyOptions(selfController: selfController, sourceNode: sourceNode, getContextController: {
return getContextController?()
}, selectionState: replySelectionState) {
sources.append(source)
}
var forwardDismissedForCancel: (() -> Void)?
if let (source, dismissedForCancel) = chatForwardOptions(selfController: selfController, sourceNode: sourceNode, getContextController: {
return getContextController?()
@ -34,11 +40,6 @@ private func presentChatInputOptions(selfController: ChatControllerImpl, sourceN
forwardDismissedForCancel = dismissedForCancel
sources.append(source)
}
if let source = chatReplyOptions(selfController: selfController, sourceNode: sourceNode, getContextController: {
return getContextController?()
}, selectionState: replySelectionState) {
sources.append(source)
}
if let source = chatLinkOptions(selfController: selfController, sourceNode: sourceNode, getContextController: {
return getContextController?()
@ -744,10 +745,9 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD
guard let selfController else {
return
}
//selfController.updateChatPresentationInterfaceState(interactive: false, { $0.updatedInterfaceState({ $0.withUpdatedForwardMessageIds(forwardMessageIds) }) })
//selfController.controllerInteraction?.sendCurrentMessage(false)
let _ = selfController
selfController.chatDisplayNode.dismissUrlPreview()
let _ = chatController
f(.default)

View File

@ -6752,6 +6752,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
info.1.dispose()
}
self.urlPreviewQueryState?.1.dispose()
self.editingUrlPreviewQueryState?.1.dispose()
self.audioRecorderDisposable?.dispose()
self.audioRecorderStatusDisposable?.dispose()
self.videoRecorderDisposable?.dispose()
@ -9806,7 +9807,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
})))
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil)
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil, animated: true)
}
return
} else {
@ -9825,7 +9826,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
})))
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil)
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil, animated: true)
return
} else {
@ -18058,7 +18059,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if canDisplayContextMenu, let contextController = contextController {
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil)
contextController.setItems(.single(ContextController.Items(content: .list(contextItems))), minHeight: nil, animated: true)
} else {
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in

View File

@ -1153,8 +1153,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
self.replyRecognizer = replyRecognizer
self.view.addGestureRecognizer(replyRecognizer)
if let item = self.item, let subject = item.associatedData.subject, case .messageOptions = subject {
//self.tapRecognizer?.isEnabled = false
if let item = self.item, let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject {
if case .link = info {
} else {
self.tapRecognizer?.isEnabled = false
}
self.replyRecognizer?.isEnabled = false
}
}
@ -3578,8 +3581,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
strongSelf.mainContextSourceNode.layoutUpdated?(strongSelf.mainContextSourceNode.bounds.size, animation)
}
if let subject = item.associatedData.subject, case .messageOptions = subject {
//strongSelf.tapRecognizer?.isEnabled = false
if let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject {
if case .link = info {
} else {
strongSelf.tapRecognizer?.isEnabled = false
}
strongSelf.replyRecognizer?.isEnabled = false
strongSelf.mainContainerNode.isGestureEnabled = false
for contentContainer in strongSelf.contentContainers {

View File

@ -284,7 +284,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
return (contentWidth, { boundingWidth in
let baseAvatarFrame = CGRect(origin: CGPoint(x: layoutConstants.text.bubbleInsets.right, y: layoutConstants.text.bubbleInsets.top), size: avatarSize)
let (buttonSize, buttonApply) = continueLayout(boundingWidth - layoutConstants.text.bubbleInsets.right * 2.0)
let (buttonSize, buttonApply) = continueLayout(boundingWidth - layoutConstants.text.bubbleInsets.right * 2.0, 33.0)
let buttonSpacing: CGFloat = 4.0
let statusSizeAndApply = statusSuggestedWidthAndContinue?.1(boundingWidth - sideInsets)

View File

@ -387,7 +387,7 @@ class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode {
let contentWidth = maxContentWidth + layoutConstants.text.bubbleInsets.right * 2.0
return (contentWidth, { boundingWidth in
let (buttonSize, buttonApply) = continueLayout(boundingWidth - layoutConstants.text.bubbleInsets.right * 2.0)
let (buttonSize, buttonApply) = continueLayout(boundingWidth - layoutConstants.text.bubbleInsets.right * 2.0, 33.0)
let buttonSpacing: CGFloat = 4.0
let (channelButtonSize, channelButtonApply) = continueChannelLayout(boundingWidth - layoutConstants.text.bubbleInsets.right * 2.0)

View File

@ -511,8 +511,13 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
let (top, bottom, dateAtBottom) = self.mergedWithItems(top: previousItem, bottom: nextItem)
var disableDate = self.disableDate
if let subject = self.associatedData.subject, case let .messageOptions(_, _, info) = subject, case .reply = info {
disableDate = true
if let subject = self.associatedData.subject, case let .messageOptions(_, _, info) = subject {
switch info {
case .reply, .link:
disableDate = true
default:
break
}
}
let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom && !disableDate)

View File

@ -67,7 +67,7 @@ final class ChatMessageUnsupportedBubbleContentNode: ChatMessageBubbleContentNod
var actionButtonSizeAndApply: ((CGSize, () -> ChatMessageAttachedContentButtonNode))?
let refinedButtonWidth = max(boundingWidth - insets.left - insets.right, buttonWidth)
let (size, apply) = continueActionButtonLayout(refinedButtonWidth)
let (size, apply) = continueActionButtonLayout(refinedButtonWidth, 33.0)
actionButtonSizeAndApply = (size, apply)
let adjustedBoundingSize = CGSize(width: refinedButtonWidth + insets.left + insets.right, height: insets.bottom + size.height)

View File

@ -2550,7 +2550,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
return ContextController.Items(content: .list(items))
}, minHeight: nil)
}, minHeight: nil, animated: true)
})))
}
if strongSelf.searchDisplayController == nil {
@ -2700,7 +2700,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
return ContextController.Items(content: .list(items))
}, minHeight: nil)
}, minHeight: nil, animated: true)
})))
}
@ -5538,7 +5538,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}, action: { [weak self] c, f in
self?.openReport(type: .default, contextController: c, backAction: { c in
if let mainItemsImpl = mainItemsImpl {
c.setItems(mainItemsImpl() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
c.setItems(mainItemsImpl() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil, animated: true)
}
})
})))
@ -6792,7 +6792,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
if let contextController = contextController {
contextController.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil)
contextController.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil, animated: true)
} else {
strongSelf.state = strongSelf.state.withHighlightedButton(.voiceChat)
if let (layout, navigationHeight) = strongSelf.validLayout {
@ -6888,7 +6888,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
if let contextController = contextController {
contextController.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil)
contextController.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil, animated: true)
} else {
strongSelf.state = strongSelf.state.withHighlightedButton(.voiceChat)
if let (layout, navigationHeight) = strongSelf.validLayout {