From fad420389260ee5f686201cc0e990d0b48a032fc Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Tue, 21 Oct 2025 20:57:40 +0400 Subject: [PATCH] Update --- .../Chat/ChatTextInputPanelNode/BUILD | 1 + .../Sources/ChatTextInputPanelComponent.swift | 4 + .../Sources/ChatTextInputPanelNode.swift | 116 ++++++++++++------ .../Sources/StarReactionButtonComponent.swift | 4 +- .../Sources/StoryContainerScreen.swift | 1 + .../StoryContentLiveChatComponent.swift | 2 +- .../StoryItemSetContainerComponent.swift | 6 - ...StoryItemSetContainerViewSendMessage.swift | 51 +++++++- .../RemovePrice.imageset/Contents.json | 12 ++ .../RemovePrice.imageset/dollarcrossed.pdf | Bin 0 -> 5614 bytes .../Text/Comments.imageset/Contents.json | 12 ++ .../Text/Comments.imageset/hidecomments.pdf | Bin 0 -> 8023 bytes 12 files changed, 160 insertions(+), 49 deletions(-) create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/Contents.json create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/dollarcrossed.pdf create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Input/Text/Comments.imageset/Contents.json create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Input/Text/Comments.imageset/hidecomments.pdf diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/BUILD index bc3258857c..c2ce20425f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/BUILD @@ -64,6 +64,7 @@ swift_library( "//submodules/TelegramUI/Components/Chat/ChatRecordingPreviewInputPanelNode", "//submodules/TelegramUI/Components/Chat/ChatInputContextPanelNode", "//submodules/TelegramUI/Components/AnimatedTextComponent", + "//submodules/TelegramUI/Components/RasterizedCompositionComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift index 31797ea02e..a17ba719e3 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift @@ -785,6 +785,10 @@ public final class ChatTextInputPanelComponent: Component { case .attach: panelNode.customLeftAction = nil case let .toggleExpanded(isVisible, isExpanded, hasUnseen): + var isVisible = isVisible + if component.insets.bottom > 40.0 { + isVisible = false + } panelNode.customLeftAction = .toggleExpanded(isVisible: isVisible, isExpanded: isExpanded, hasUnseen: hasUnseen) } } else { diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift index 4f15ef83a9..f610f883c9 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift @@ -57,6 +57,7 @@ import ChatTextInputAudioRecordingCancelIndicator import ChatRecordingViewOnceButtonNode import ChatRecordingPreviewInputPanelNode import ChatInputContextPanelNode +import RasterizedCompositionComponent private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers]) @@ -257,6 +258,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg public let attachmentButton: HighlightTrackingButton public let attachmentButtonBackground: GlassBackgroundView public let attachmentButtonIcon: GlassBackgroundView.ContentImageView + private var commentsButtonIcon: RasterizedCompositionMonochromeLayer? + private var commentsButtonContentsLayer: RasterizedCompositionImageLayer? + private var commentsButtonDotLayer: RasterizedCompositionImageLayer? private var attachmentButtonUnseenIcon: UIImageView? public let attachmentButtonDisabledNode: HighlightableButtonNode @@ -890,7 +894,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg self.glassBackgroundContainer.contentView.addSubview(self.sendActionButtons.view) self.glassBackgroundContainer.contentView.addSubview(self.mediaActionButtons.view) - self.glassBackgroundContainer.contentView.addSubview(self.counterTextNode.view) + self.textInputContainerBackgroundView.contentView.addSubview(self.counterTextNode.view) self.glassBackgroundContainer.contentView.addSubview(self.slowModeButton.view) @@ -1749,7 +1753,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg if let customLeftAction = self.customLeftAction { switch customLeftAction { case .toggleExpanded: - self.attachmentButtonIcon.image = UIImage(bundleImageName: "Chat/Context Menu/ReactionExpandArrow")?.withRenderingMode(.alwaysTemplate) + self.attachmentButtonIcon.image = nil self.attachmentButtonIcon.tintColor = interfaceState.theme.chat.inputPanel.panelControlColor } } else if interfaceState.interfaceState.mediaDraftState != nil { @@ -1790,7 +1794,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg if let customLeftAction = self.customLeftAction { switch customLeftAction { case .toggleExpanded: - self.attachmentButtonIcon.image = UIImage(bundleImageName: "Chat/Context Menu/ReactionExpandArrow")?.withRenderingMode(.alwaysTemplate) + self.attachmentButtonIcon.image = nil self.attachmentButtonIcon.tintColor = interfaceState.theme.chat.inputPanel.panelControlColor } } else if interfaceState.interfaceState.mediaDraftState != nil { @@ -1943,12 +1947,55 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg if let customLeftAction = self.customLeftAction { switch customLeftAction { case let .toggleExpanded(_, isExpanded, hasUnseen): - var iconTransform = CATransform3DIdentity - iconTransform = CATransform3DTranslate(iconTransform, 0.0, 1.0, 0.0) - if !isExpanded { - iconTransform = CATransform3DRotate(iconTransform, CGFloat.pi, 0.0, 0.0, 1.0) + let _ = isExpanded + let commentsButtonIcon: RasterizedCompositionMonochromeLayer + if let current = self.commentsButtonIcon { + commentsButtonIcon = current + } else { + commentsButtonIcon = RasterizedCompositionMonochromeLayer() + self.commentsButtonIcon = commentsButtonIcon + self.attachmentButtonBackground.contentView.layer.addSublayer(commentsButtonIcon) + } + + let commentsButtonContentsLayer: RasterizedCompositionImageLayer + if let current = self.commentsButtonContentsLayer { + commentsButtonContentsLayer = current + } else { + commentsButtonContentsLayer = RasterizedCompositionImageLayer() + self.commentsButtonContentsLayer = commentsButtonContentsLayer + commentsButtonIcon.contentsLayer.addSublayer(commentsButtonContentsLayer) + commentsButtonContentsLayer.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/Comments"), color: .white) + } + + let commentsButtonDotLayer: RasterizedCompositionImageLayer + if let current = self.commentsButtonDotLayer { + commentsButtonDotLayer = current + } else { + commentsButtonDotLayer = RasterizedCompositionImageLayer() + self.commentsButtonDotLayer = commentsButtonDotLayer + commentsButtonIcon.contentsLayer.addSublayer(commentsButtonDotLayer) + commentsButtonDotLayer.image = generateStretchableFilledCircleImage(diameter: 10.0 + 1.0 * 2.0, color: .black) + } + + let iconFrame = CGRect(origin: CGPoint(), size: CGSize(width: 40.0, height: 40.0)) + commentsButtonIcon.position = iconFrame.center + commentsButtonIcon.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) + + commentsButtonIcon.contentsLayer.position = CGRect(origin: CGPoint(), size: iconFrame.size).center + commentsButtonIcon.contentsLayer.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) + + commentsButtonIcon.maskedLayer.position = CGRect(origin: CGPoint(), size: iconFrame.size).center + commentsButtonIcon.maskedLayer.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) + commentsButtonIcon.maskedLayer.backgroundColor = UIColor.white.cgColor + + if let image = commentsButtonContentsLayer.image { + commentsButtonContentsLayer.frame = image.size.centered(in: commentsButtonIcon.bounds) + } + + let dotFrame = CGRect(origin: CGPoint(x: 40.0 - 7.0 - 10.0, y: 7.0), size: CGSize(width: 10.0, height: 10.0)) + if let image = commentsButtonDotLayer.image { + commentsButtonDotLayer.frame = image.size.centered(in: dotFrame) } - transition.updateTransform(layer: self.attachmentButtonIcon.layer, transform: iconTransform) if hasUnseen { let attachmentButtonUnseenIcon: UIImageView @@ -1958,13 +2005,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg attachmentButtonUnseenIcon = UIImageView() self.attachmentButtonUnseenIcon = attachmentButtonUnseenIcon self.attachmentButtonBackground.contentView.addSubview(attachmentButtonUnseenIcon) - attachmentButtonUnseenIcon.image = generateStretchableFilledCircleImage(diameter: 6.0, color: .white)?.withRenderingMode(.alwaysTemplate) + attachmentButtonUnseenIcon.image = generateStretchableFilledCircleImage(diameter: 10.0, color: .white)?.withRenderingMode(.alwaysTemplate) } attachmentButtonUnseenIcon.tintColor = interfaceState.theme.list.itemAccentColor - - if let image = attachmentButtonUnseenIcon.image { - attachmentButtonUnseenIcon.frame = CGRect(origin: CGPoint(x: 40.0 - 8.0 - image.size.width, y: 8.0), size: image.size) - } + attachmentButtonUnseenIcon.frame = dotFrame + commentsButtonDotLayer.isHidden = false } else { if let attachmentButtonUnseenIcon = self.attachmentButtonUnseenIcon { self.attachmentButtonUnseenIcon = nil @@ -1973,10 +2018,23 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg attachmentButtonUnseenIcon?.removeFromSuperview() }) } + commentsButtonDotLayer.isHidden = true } } } else { - self.attachmentButtonIcon.layer.transform = CATransform3DIdentity + if let commentsButtonIcon = self.commentsButtonIcon { + self.commentsButtonIcon = nil + transition.updateTransformScale(layer: commentsButtonIcon, scale: 0.001) + transition.updateAlpha(layer: commentsButtonIcon, alpha: 0.0, completion: { [weak commentsButtonIcon] _ in + commentsButtonIcon?.removeFromSuperlayer() + }) + } + if let _ = self.commentsButtonContentsLayer { + self.commentsButtonContentsLayer = nil + } + if let _ = self.commentsButtonDotLayer { + self.commentsButtonDotLayer = nil + } if let attachmentButtonUnseenIcon = self.attachmentButtonUnseenIcon { self.attachmentButtonUnseenIcon = nil transition.updateTransformScale(layer: attachmentButtonUnseenIcon.layer, scale: 0.001) @@ -2445,8 +2503,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg leftInset += leftMenuInset let composeButtonsOffset: CGFloat = 0.0 - - self.updateCounterTextNode(transition: transition) var textInputViewRealInsets = UIEdgeInsets() if let presentationInterfaceState = self.presentationInterfaceState { @@ -2575,6 +2631,8 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg transition.updateFrame(view: self.accessoryPanelContainer, frame: CGRect(origin: CGPoint(), size: textInputContainerBackgroundFrame.size)) transition.updateFrame(view: self.textInputContainerBackgroundView, frame: textInputContainerBackgroundFrame) + self.updateCounterTextNode(backgroundSize: textInputContainerBackgroundFrame.size, transition: transition) + var textInputContainerBackgroundTransition = ComponentTransition(transition) if useBounceAnimation, case let .animated(_, curve) = transition, case .spring = curve { textInputContainerBackgroundTransition = textInputContainerBackgroundTransition.withUserData(GlassBackgroundView.TransitionFlagBounce()) @@ -3235,8 +3293,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg self.interfaceInteraction?.updateTextInputStateAndMode({ _, inputMode in return (inputTextState, inputMode) }) self.interfaceInteraction?.updateInputLanguage({ _ in return textInputNode.textInputMode?.primaryLanguage }) self.updateTextNodeText(animated: true) - - self.updateCounterTextNode(transition: .immediate) } } @@ -3664,7 +3720,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg } } - private func updateCounterTextNode(transition: ContainedViewLayoutTransition) { + private func updateCounterTextNode(backgroundSize: CGSize, transition: ContainedViewLayoutTransition) { var inputTextMaxLength: Int32? if let customInputTextMaxLength = self.customInputTextMaxLength { inputTextMaxLength = Int32(customInputTextMaxLength) @@ -3686,26 +3742,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg } else { self.counterTextNode.attributedText = NSAttributedString(string: "", font: counterFont, textColor: .black) } - - if let (width, leftInset, rightInset, bottomInset, _, maxHeight, _, metrics, _, _) = self.validLayout, let interfaceState = self.presentationInterfaceState { - var composeButtonsOffset: CGFloat = 0.0 - if self.extendedSearchLayout { - composeButtonsOffset = 40.0 - } - let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - self.leftMenuInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset, sendActionControlsWidth: self.sendActionButtons.bounds.width, maxHeight: maxHeight, metrics: metrics, bottomInset: bottomInset, interfaceState: interfaceState) - let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics, bottomInset: bottomInset) - var textFieldMinHeight: CGFloat = 33.0 - if let presentationInterfaceState = self.presentationInterfaceState { - textFieldMinHeight = calclulateTextFieldMinHeight(presentationInterfaceState, metrics: metrics) - } - let minimalHeight: CGFloat = 14.0 + textFieldMinHeight - - let counterSize = self.counterTextNode.updateLayout(CGSize(width: 40.0, height: 40.0)) - let actionButtonsOriginX = width - rightInset - 43.0 - UIScreenPixel + composeButtonsOffset - let counterFrame = CGRect(origin: CGPoint(x: actionButtonsOriginX, y: panelHeight - minimalHeight - counterSize.height + 3.0), size: CGSize(width: width - actionButtonsOriginX - rightInset, height: counterSize.height)) - transition.updateFrame(node: self.counterTextNode, frame: counterFrame) - } + let counterSize = self.counterTextNode.updateLayout(CGSize(width: 40.0, height: 40.0)) + let counterFrame = CGRect(origin: CGPoint(x: backgroundSize.width - 11.0 - counterSize.width, y: 4.0), size: CGSize(width: counterSize.width, height: counterSize.height)) + transition.updateFrame(node: self.counterTextNode, frame: counterFrame) } private func installEmojiSuggestionPreviewGesture(hostView: UIView) { diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift index bc957b05dd..594976a7d7 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift @@ -146,9 +146,9 @@ final class StarReactionButtonComponent: Component { let backgroundTintColor: GlassBackgroundView.TintColor if component.isFilled { - backgroundTintColor = .init(kind: .panel, color: component.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) - } else { backgroundTintColor = .init(kind: .custom, color: UIColor(rgb: 0xFFB10D)) + } else { + backgroundTintColor = .init(kind: .panel, color: component.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) } self.backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: component.theme.overallDarkAppearance, tintColor: backgroundTintColor, isInteractive: true, transition: transition) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift index a30e67b74a..834f8bfb5e 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift @@ -1335,6 +1335,7 @@ private final class StoryContainerScreenComponent: Component { hasTrending: true, hasSearch: true, hideBackground: true, + maskEdge: .clip, sendGif: nil ) ) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift index 0edb51d73c..f8d1b7ef7c 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift @@ -684,7 +684,7 @@ final class StoryContentLiveChatComponent: Component { theme: component.theme, layout: StoryLiveChatMessageComponent.Layout( isFlipped: true, - insets: UIEdgeInsets(top: 9.0, left: 20.0, bottom: 9.0, right: 20.0), + insets: UIEdgeInsets(top: 9.0, left: 24.0, bottom: 9.0, right: 20.0), fitToWidth: false, transparentBackground: true ), diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 74fdb9f34b..606a4de6f1 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2988,12 +2988,6 @@ public final class StoryItemSetContainerComponent: Component { return } - if let visibleItemView = self.visibleItems[component.slice.item.id]?.view.view as? StoryItemContentComponent.View { - if !(visibleItemView.liveChatState?.isExpanded ?? true) { - visibleItemView.toggleLiveChatExpanded() - } - } - self.sendMessageContext.performSendMessageAction(view: self) }, sendMessageOptionsAction: { [weak self] sourceView, gesture in diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index fea168d6e8..f71ebdd3f6 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -244,10 +244,12 @@ final class StoryItemSetContainerSendMessage { ) } + var animateIn = false let inputMediaNode: ChatEntityKeyboardInputNode if let current = self.inputMediaNode { inputMediaNode = current } else { + animateIn = true inputMediaNode = ChatEntityKeyboardInputNode( context: context, currentInputData: updatedInputData, @@ -308,7 +310,7 @@ final class StoryItemSetContainerSendMessage { let inputNodeHeight = heightAndOverflow.0 let inputNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - inputNodeHeight), size: CGSize(width: availableSize.width, height: inputNodeHeight)) - do { + if animateIn { let inputNodeFrame = inputNodeFrame.offsetBy(dx: 0.0, dy: inputNodeHeight) ComponentTransition.immediate.setFrame(layer: inputMediaNode.layer, frame: inputNodeFrame) } @@ -412,7 +414,7 @@ final class StoryItemSetContainerSendMessage { self.performPaidMessageAction(view: view) }))) if self.currentLiveStreamMessageStars != nil { - items.append(.action(ContextMenuActionItem(text: "Remove Stars", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconSuggestPost"), color: theme.contextMenu.primaryColor) + items.append(.action(ContextMenuActionItem(text: "Remove Stars", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/RemovePrice"), color: theme.contextMenu.primaryColor) }, action: { [weak self, weak view] _, a in a(.default) @@ -621,6 +623,51 @@ final class StoryItemSetContainerSendMessage { switch inputPanelView.getSendMessageInput() { case let .text(text): if !text.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + var maxInputLength: Int? + var maxEmojiCount: Int? + let params = GroupCallMessagesContext.getStarAmountParamMapping(value: self.currentLiveStreamMessageStars?.value ?? 0) + maxInputLength = params.maxLength + maxEmojiCount = params.emojiCount + + var isSendDisabled = false + if let maxInputLength, text.string.count > maxInputLength { + isSendDisabled = true + } + if let maxEmojiCount { + var emojiCount = 0 + let nsString = text.string as NSString + var processedRanges = Set>() + nsString.enumerateSubstrings(in: NSRange(location: 0, length: nsString.length), options: .byComposedCharacterSequences, using: { + substring, range, _, _ in + if let substring, substring.isSingleEmoji { + emojiCount += 1 + processedRanges.insert(range.lowerBound ..< range.upperBound) + } + }) + let entities = generateChatInputTextEntities(text, generateLinks: false) + for entity in entities { + if case .CustomEmoji = entity.type { + if !processedRanges.contains(entity.range) { + emojiCount += 1 + } + } + } + if emojiCount > maxEmojiCount { + isSendDisabled = true + } + } + + if isSendDisabled { + self.performPaidMessageAction(view: view) + return + } + + if let visibleItemView = view.visibleItems[component.slice.item.id]?.view.view as? StoryItemContentComponent.View { + if !(visibleItemView.liveChatState?.isExpanded ?? true) { + visibleItemView.toggleLiveChatExpanded() + } + } + let entities = generateChatInputTextEntities(text) call.sendMessage(text: text.string, entities: entities, paidStars: self.currentLiveStreamMessageStars?.value) diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/Contents.json new file mode 100644 index 0000000000..57461c344a --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "dollarcrossed.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/dollarcrossed.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/RemovePrice.imageset/dollarcrossed.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2714bd65cdb7b27e1749947cc4e03535a9c54bfe GIT binary patch literal 5614 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 GYX1XTwO&F1 literal 0 HcmV?d00001