From ff32f344055cce4d21800089448817b1e8dbc159 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Tue, 4 Nov 2025 14:22:43 +0400 Subject: [PATCH] Various improvements --- .../Sources/PresentationCallManager.swift | 5 +- .../Sources/PresentationGroupCall.swift | 4 +- .../Sources/VideoChatScreen.swift | 3 +- .../Sources/ChatTextInputPanelComponent.swift | 7 ++ .../Sources/ChatTextInputPanelNode.swift | 30 ++++++- .../Sources/MessageInputPanelComponent.swift | 77 +++++++++++------- .../StoryContentLiveChatComponent.swift | 64 +++++++++++++-- .../Sources/StoryItemContentComponent.swift | 16 +++- .../StoryItemSetContainerComponent.swift | 2 + .../Text/CommensCross.imageset/Contents.json | 12 +++ .../Text/CommensCross.imageset/comments2.pdf | Bin 0 -> 4530 bytes .../Text/Comments.imageset/Contents.json | 2 +- .../{hidecomments.pdf => comments1.pdf} | Bin 8023 -> 7812 bytes 13 files changed, 173 insertions(+), 49 deletions(-) create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/Contents.json create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/comments2.pdf rename submodules/TelegramUI/Images.xcassets/Chat/Input/Text/Comments.imageset/{hidecomments.pdf => comments1.pdf} (53%) diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 5160053e8c..787a312b89 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -233,6 +233,7 @@ public struct PresentationGroupCallState: Equatable { public var isVideoEnabled: Bool public var isVideoWatchersLimitReached: Bool public var isMyVideoActive: Bool + public var isUnifiedStream: Bool public init( myPeerId: EnginePeer.Id, @@ -251,7 +252,8 @@ public struct PresentationGroupCallState: Equatable { subscribedToScheduled: Bool, isVideoEnabled: Bool, isVideoWatchersLimitReached: Bool, - isMyVideoActive: Bool + isMyVideoActive: Bool, + isUnifiedStream: Bool ) { self.myPeerId = myPeerId self.networkState = networkState @@ -270,6 +272,7 @@ public struct PresentationGroupCallState: Equatable { self.isVideoEnabled = isVideoEnabled self.isVideoWatchersLimitReached = isVideoWatchersLimitReached self.isMyVideoActive = isMyVideoActive + self.isUnifiedStream = isUnifiedStream } } diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 143e630ed0..1246bb7063 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -38,7 +38,8 @@ private extension PresentationGroupCallState { subscribedToScheduled: subscribedToScheduled, isVideoEnabled: false, isVideoWatchersLimitReached: false, - isMyVideoActive: false + isMyVideoActive: false, + isUnifiedStream: false ) } } @@ -2664,6 +2665,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.stateValue.scheduleTimestamp = state.scheduleTimestamp self.stateValue.isVideoEnabled = state.isVideoEnabled && otherParticipantsWithVideo < state.unmutedVideoLimit self.stateValue.isVideoWatchersLimitReached = videoWatchingParticipants >= configuration.videoParticipantsMaxCount + self.stateValue.isUnifiedStream = state.isStream self.summaryInfoState.set(.single(SummaryInfoState(info: GroupCallInfo( id: callInfo.id, diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift index e83ccdea6d..491c1f9e37 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift @@ -1218,7 +1218,8 @@ final class VideoChatScreenComponent: Component { subscribedToScheduled: false, isVideoEnabled: true, isVideoWatchersLimitReached: false, - isMyVideoActive: false + isMyVideoActive: false, + isUnifiedStream: false ) return .single((callState, invitedPeers.compactMap({ peer -> VideoChatScreenComponent.InvitedPeer? in diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift index fc624f6476..3822f99c74 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift @@ -145,6 +145,7 @@ public final class ChatTextInputPanelComponent: Component { let rightAction: RightAction? let sendAsConfiguration: SendAsConfiguration? let placeholder: String + let isEnabled: Bool let paidMessagePrice: StarsAmount? let sendColor: UIColor? let isSendDisabled: Bool @@ -166,6 +167,7 @@ public final class ChatTextInputPanelComponent: Component { rightAction: RightAction?, sendAsConfiguration: SendAsConfiguration?, placeholder: String, + isEnabled: Bool, paidMessagePrice: StarsAmount?, sendColor: UIColor?, isSendDisabled: Bool, @@ -186,6 +188,7 @@ public final class ChatTextInputPanelComponent: Component { self.rightAction = rightAction self.sendAsConfiguration = sendAsConfiguration self.placeholder = placeholder + self.isEnabled = isEnabled self.paidMessagePrice = paidMessagePrice self.sendColor = sendColor self.isSendDisabled = isSendDisabled @@ -228,6 +231,9 @@ public final class ChatTextInputPanelComponent: Component { if lhs.placeholder != rhs.placeholder { return false } + if lhs.isEnabled != rhs.isEnabled { + return false + } if lhs.paidMessagePrice != rhs.paidMessagePrice { return false } @@ -829,6 +835,7 @@ public final class ChatTextInputPanelComponent: Component { } panelNode.customPlaceholder = component.placeholder + panelNode.customIsDisabled = !component.isEnabled if let leftAction = component.leftAction { switch leftAction.kind { diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift index 045df51160..a43059a286 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift @@ -264,6 +264,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg public let attachmentButtonBackground: GlassBackgroundView public let attachmentButtonIcon: GlassBackgroundView.ContentImageView private var commentsButtonIcon: RasterizedCompositionMonochromeLayer? + private var commentsButtonCenterIcon: UIImageView? private var commentsButtonContentsLayer: RasterizedCompositionImageLayer? private var commentsButtonDotLayer: RasterizedCompositionImageLayer? private var attachmentButtonUnseenIcon: UIImageView? @@ -393,6 +394,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg } public var customPlaceholder: String? + public var customIsDisabled: Bool = false public var customLeftAction: LeftAction? public var customRightAction: RightAction? public var customSendColor: UIColor? @@ -1495,6 +1497,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg } } } + if self.customIsDisabled { + sendingTextDisabled = true + } self.sendingTextDisabled = sendingTextDisabled self.textInputNode?.isUserInteractionEnabled = !sendingTextDisabled @@ -1941,7 +1946,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg if let customLeftAction = self.customLeftAction { switch customLeftAction { case let .toggleExpanded(_, isExpanded, hasUnseen): - let _ = isExpanded let commentsButtonIcon: RasterizedCompositionMonochromeLayer if let current = self.commentsButtonIcon { commentsButtonIcon = current @@ -1951,6 +1955,17 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg self.attachmentButtonBackground.contentView.layer.addSublayer(commentsButtonIcon) } + let commentsButtonCenterIcon: UIImageView + if let current = self.commentsButtonCenterIcon { + commentsButtonCenterIcon = current + } else { + commentsButtonCenterIcon = UIImageView() + self.commentsButtonCenterIcon = commentsButtonCenterIcon + self.attachmentButtonBackground.contentView.addSubview(commentsButtonCenterIcon) + commentsButtonCenterIcon.image = UIImage(bundleImageName: "Chat/Input/Text/CommensCross")?.withRenderingMode(.alwaysTemplate) + } + commentsButtonCenterIcon.tintColor = interfaceState.theme.chat.inputPanel.panelControlColor + let commentsButtonContentsLayer: RasterizedCompositionImageLayer if let current = self.commentsButtonContentsLayer { commentsButtonContentsLayer = current @@ -1975,6 +1990,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg commentsButtonIcon.position = iconFrame.center commentsButtonIcon.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) + commentsButtonCenterIcon.center = iconFrame.center + if let image = commentsButtonCenterIcon.image { + commentsButtonCenterIcon.bounds = image.size.centered(in: iconFrame) + } + transition.updateTransformRotation(view: commentsButtonCenterIcon, angle: !isExpanded ? (CGFloat.pi * 3.0 / 4.0) : 0.0) + commentsButtonIcon.contentsLayer.position = CGRect(origin: CGPoint(), size: iconFrame.size).center commentsButtonIcon.contentsLayer.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) @@ -2036,6 +2057,13 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg attachmentButtonUnseenIcon?.removeFromSuperview() }) } + if let commentsButtonCenterIcon = self.commentsButtonCenterIcon { + self.commentsButtonCenterIcon = nil + transition.updateTransformScale(layer: commentsButtonCenterIcon.layer, scale: 0.001) + transition.updateAlpha(layer: commentsButtonCenterIcon.layer, alpha: 0.0, completion: { [weak commentsButtonCenterIcon] _ in + commentsButtonCenterIcon?.removeFromSuperview() + }) + } } var textFieldMinHeight: CGFloat = 33.0 diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift index 18062c57a2..8bed93166b 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift @@ -174,11 +174,15 @@ public final class MessageInputPanelComponent: Component { } public struct LiveChatState: Equatable { + public var isEnabled: Bool public var isExpanded: Bool + public var isEmpty: Bool public var hasUnseenMessages: Bool - public init(isExpanded: Bool, hasUnseenMessages: Bool) { + public init(isEnabled: Bool, isExpanded: Bool, isEmpty: Bool, hasUnseenMessages: Bool) { + self.isEnabled = isEnabled self.isExpanded = isExpanded + self.isEmpty = isEmpty self.hasUnseenMessages = hasUnseenMessages } } @@ -929,35 +933,37 @@ public final class MessageInputPanelComponent: Component { self.currentInputMode = inputMode var inlineActions: [ChatTextInputPanelComponent.InlineAction] = [] - if component.paidMessageAction != nil && self.textInputPanelExternalState.textInputState.inputText.length == 0 { - inlineActions.append(ChatTextInputPanelComponent.InlineAction( - kind: .paidMessage, - action: { [weak self] in - guard let self else { - return + if component.liveChatState?.isEnabled == true { + if component.paidMessageAction != nil && self.textInputPanelExternalState.textInputState.inputText.length == 0 { + inlineActions.append(ChatTextInputPanelComponent.InlineAction( + kind: .paidMessage, + action: { [weak self] in + guard let self else { + return + } + self.component?.paidMessageAction?() } - self.component?.paidMessageAction?() + )) + } else if let inputMode { + let mappedInputMode: ChatTextInputPanelComponent.InputMode + switch inputMode { + case .text: + mappedInputMode = .text + case .emoji: + mappedInputMode = .emoji + case .stickers: + mappedInputMode = .stickers } - )) - } else if let inputMode { - let mappedInputMode: ChatTextInputPanelComponent.InputMode - switch inputMode { - case .text: - mappedInputMode = .text - case .emoji: - mappedInputMode = .emoji - case .stickers: - mappedInputMode = .stickers + inlineActions.append(ChatTextInputPanelComponent.InlineAction( + kind: .inputMode(mappedInputMode), + action: { [weak self] in + guard let self, let component = self.component else { + return + } + component.inputModeAction?() + } + )) } - inlineActions.append(ChatTextInputPanelComponent.InlineAction( - kind: .inputMode(mappedInputMode), - action: { [weak self] in - guard let self, let component = self.component else { - return - } - component.inputModeAction?() - } - )) } let placeholder: String @@ -1026,11 +1032,18 @@ public final class MessageInputPanelComponent: Component { strings: component.strings, chatPeerId: component.chatLocation?.peerId ?? component.context.account.peerId, inlineActions: inlineActions, - leftAction: ChatTextInputPanelComponent.LeftAction(kind: .toggleExpanded(isVisible: component.liveChatState != nil, isExpanded: component.liveChatState?.isExpanded ?? true, hasUnseen: component.liveChatState?.hasUnseenMessages ?? false), action: { [weak self] in + leftAction: ChatTextInputPanelComponent.LeftAction(kind: .toggleExpanded(isVisible: component.liveChatState?.isEnabled == true, isExpanded: component.liveChatState?.isExpanded ?? true, hasUnseen: component.liveChatState?.hasUnseenMessages ?? false), action: { [weak self] in guard let self, let component = self.component else { return } - component.toggleLiveChatExpanded?() + guard let inputPanelView = self.inputPanel?.view as? ChatTextInputPanelComponent.View else { + return + } + if let liveChatState = component.liveChatState, liveChatState.isEmpty { + inputPanelView.activateInput() + } else { + component.toggleLiveChatExpanded?() + } }), rightAction: ChatTextInputPanelComponent.RightAction(kind: .stars(count: Int(component.starStars?.totalStars ?? 0), isFilled: component.starStars?.hasOutgoingStars ?? false), action: { [weak self] sourceView in guard let self, let component = self.component else { @@ -1043,8 +1056,10 @@ public final class MessageInputPanelComponent: Component { } component.sendStarsAction?(sourceView, true) }), - sendAsConfiguration: sendAsConfiguration, - placeholder: placeholder, + sendAsConfiguration: component.liveChatState?.isEnabled == true ? sendAsConfiguration : nil, + //TODO:localize + placeholder: component.liveChatState?.isEnabled == true ? placeholder : "Comments are disabled", + isEnabled: component.liveChatState?.isEnabled == true, paidMessagePrice: component.sendPaidMessageStars, sendColor: component.sendPaidMessageStars.flatMap { value in let params = LiveChatMessageParams(appConfig: component.context.currentAppConfiguration.with({ $0 })) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift index 17600e6a66..8075fd2b21 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift @@ -21,6 +21,7 @@ import AdminUserActionsSheet final class StoryContentLiveChatComponent: Component { final class External { + fileprivate(set) var isEmpty: Bool = false fileprivate(set) var hasUnseenMessages: Bool = false init() { @@ -268,6 +269,35 @@ final class StoryContentLiveChatComponent: Component { self.state?.updated(transition: .spring(duration: 0.4)) } + private func displayDeleteMessageConfirmation(id: GroupCallMessagesContext.Message.Id) { + guard let component = self.component else { + return + } + + let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme) + let actionSheet = ActionSheetController(presentationData: presentationData) + + actionSheet.setItemGroups([ + ActionSheetItemGroup(items: [ + ActionSheetButtonItem(title: component.strings.Chat_DeleteMessagesConfirmation(1), color: .destructive, action: { [weak self, weak actionSheet] in + actionSheet?.dismissAnimated() + + guard let self, let component = self.component, let call = component.call as? PresentationGroupCallImpl else { + return + } + call.deleteMessage(id: id, reportSpam: false) + }) + ]), + ActionSheetItemGroup(items: [ + ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + }) + ]) + ]) + + component.controller()?.present(actionSheet, in: .window(.root)) + } + private func displayDeleteMessageAndBan(id: GroupCallMessagesContext.Message.Id) { Task { @MainActor [weak self] in guard let self, let component = self.component else { @@ -281,6 +311,10 @@ final class StoryContentLiveChatComponent: Component { guard let messagesState = self.messagesState, let message = messagesState.messages.first(where: { $0.id == id }) else { return } + if message.isFromAdmin { + self.displayDeleteMessageConfirmation(id: id) + return + } guard let author = message.author else { return } @@ -311,10 +345,23 @@ final class StoryContentLiveChatComponent: Component { messageCount: 1, deleteAllMessageCount: totalCount, completion: { [weak self] result in - guard let self else { + guard let self, let component = self.component, let call = component.call as? PresentationGroupCallImpl else { return } - let _ = self + + if result.deleteAll { + call.deleteAllMessages(authorId: author.id, reportSpam: result.reportSpam) + } else { + call.deleteMessage(id: id, reportSpam: result.reportSpam) + } + + if result.ban { + if component.storyPeerId == component.context.account.peerId { + let _ = component.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: author.id, isBlocked: true).startStandalone() + } else { + let _ = component.context.engine.peers.updateChannelMemberBannedRights(peerId: component.storyPeerId, memberId: author.id, rights: TelegramChatBannedRights(flags: .banReadMessages, untilDate: Int32.max)).startStandalone() + } + } } ), customTheme: defaultDarkColorPresentationTheme @@ -414,15 +461,13 @@ final class StoryContentLiveChatComponent: Component { } c?.dismiss(completion: { [weak self] in - guard let self, let component = self.component else { + guard let self else { return } - if let call = component.call as? PresentationGroupCallImpl { - if isAdmin && !isMyMessage { - self.displayDeleteMessageAndBan(id: id) - } else { - call.deleteMessage(id: id, reportSpam: false) - } + if isAdmin && !isMyMessage { + self.displayDeleteMessageAndBan(id: id) + } else { + self.displayDeleteMessageConfirmation(id: id) } }) }))) @@ -500,6 +545,7 @@ final class StoryContentLiveChatComponent: Component { self.reactionStreamView?.add(peer: peer, count: Int(state.pendingMyStars - previousMessagesState.pendingMyStars)) } } + component.external.isEmpty = state.messages.isEmpty self.messagesState = state if !self.isUpdating { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift index 7997580ae0..64272cce1b 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift @@ -112,14 +112,16 @@ final class StoryItemContentComponent: Component { struct LiveChatState { var isExpanded: Bool + var isEmpty: Bool var hasUnseenMessages: Bool var areMessagesEnabled: Bool var minMessagePrice: Int64? var starStats: StarStats? var isAdmin: Bool - init(isExpanded: Bool, hasUnseenMessages: Bool, areMessagesEnabled: Bool, minMessagePrice: Int64?, starStats: StarStats?, isAdmin: Bool) { + init(isExpanded: Bool, isEmpty: Bool, hasUnseenMessages: Bool, areMessagesEnabled: Bool, minMessagePrice: Int64?, starStats: StarStats?, isAdmin: Bool) { self.isExpanded = isExpanded + self.isEmpty = isEmpty self.hasUnseenMessages = hasUnseenMessages self.areMessagesEnabled = areMessagesEnabled self.minMessagePrice = minMessagePrice @@ -132,11 +134,13 @@ final class StoryItemContentComponent: Component { var areMessagesEnabled: Bool var minMessagePrice: Int64? var isAdmin: Bool + var isUnifiedStream: Bool - init(areMessagesEnabled: Bool, minMessagePrice: Int64?, isAdmin: Bool) { + init(areMessagesEnabled: Bool, minMessagePrice: Int64?, isAdmin: Bool, isUnifiedStream: Bool) { self.areMessagesEnabled = areMessagesEnabled self.minMessagePrice = minMessagePrice self.isAdmin = isAdmin + self.isUnifiedStream = isUnifiedStream } } @@ -220,6 +224,7 @@ final class StoryItemContentComponent: Component { return LiveChatState( isExpanded: currentInfo.isChatExpanded, + isEmpty: self.liveChatExternal.isEmpty, hasUnseenMessages: self.liveChatExternal.hasUnseenMessages, areMessagesEnabled: mediaStreamCallState?.areMessagesEnabled ?? false, minMessagePrice: mediaStreamCallState?.minMessagePrice, @@ -937,7 +942,9 @@ final class StoryItemContentComponent: Component { if case .rtc = liveStream.kind, component.isEmbeddedInCamera { } else { var videoEndpointId: String? - if let mediaStreamCallVideoState = self.mediaStreamCallVideoState { + if let mediaStreamCallState = self.mediaStreamCallState, mediaStreamCallState.isUnifiedStream { + videoEndpointId = "unified" + } else if let mediaStreamCallVideoState = self.mediaStreamCallVideoState { videoEndpointId = mediaStreamCallVideoState.videoEndpointId } let _ = mediaStream.update( @@ -1082,7 +1089,8 @@ final class StoryItemContentComponent: Component { let mappedState = MediaStreamCallState( areMessagesEnabled: state.messagesAreEnabled, minMessagePrice: state.sendPaidMessageStars, - isAdmin: state.canManageCall + isAdmin: state.canManageCall, + isUnifiedStream: state.isUnifiedStream ) if self.mediaStreamCallState != mappedState { self.mediaStreamCallState = mappedState diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index c1ce048571..3e9608cc61 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2968,7 +2968,9 @@ public final class StoryItemSetContainerComponent: Component { if let visibleItemView = self.visibleItems[component.slice.item.id]?.view.view as? StoryItemContentComponent.View { if let liveChatStateValue = visibleItemView.liveChatState { liveChatState = MessageInputPanelComponent.LiveChatState( + isEnabled: liveChatStateValue.areMessagesEnabled, isExpanded: liveChatStateValue.isExpanded, + isEmpty: liveChatStateValue.isEmpty, hasUnseenMessages: liveChatStateValue.hasUnseenMessages ) starStats = liveChatStateValue.starStats.flatMap { starStats in diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/Contents.json new file mode 100644 index 0000000000..c67ebf5c2d --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "comments2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/comments2.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Input/Text/CommensCross.imageset/comments2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f6f4a6e55783a6a4b78e6c13f63aa5d655e6f35f GIT binary patch literal 4530 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 delta 3714 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 Z1#U?y|M&BRiM$3sPNM?K%7#0){0~F9xfK8a