diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift index 925ed0ab8c..a6d7fbba03 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift @@ -3754,6 +3754,21 @@ public final class GroupCallMessagesContext { ) } + public func withDate(_ date: Int32) -> Message { + return Message( + id: self.id, + stableId: self.stableId, + isIncoming: self.isIncoming, + author: self.author, + isFromAdmin: self.isFromAdmin, + text: self.text, + entities: self.entities, + date: date, + lifetime: self.lifetime, + paidStars: self.paidStars + ) + } + public static func ==(lhs: Message, rhs: Message) -> Bool { if lhs === rhs { return true @@ -4344,10 +4359,10 @@ public final class GroupCallMessagesContext { self.processedIds.insert(Int64(id)) var state = self.state if let index = state.messages.firstIndex(where: { $0.id == Message.Id(space: .local, id: randomId) }) { - state.messages[index] = state.messages[index].withId(Message.Id(space: .remote, id: Int64(id))) + state.messages[index] = state.messages[index].withId(Message.Id(space: .remote, id: Int64(id))).withDate(Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)) } if let index = state.pinnedMessages.firstIndex(where: { $0.id == Message.Id(space: .local, id: randomId) }) { - state.pinnedMessages[index] = state.pinnedMessages[index].withId(Message.Id(space: .remote, id: Int64(id))) + state.pinnedMessages[index] = state.pinnedMessages[index].withId(Message.Id(space: .remote, id: Int64(id))).withDate(Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)) } self.state = state break @@ -4405,10 +4420,10 @@ public final class GroupCallMessagesContext { self.processedIds.insert(Int64(id)) var state = self.state if let index = state.messages.firstIndex(where: { $0.id == Message.Id(space: .local, id: pendingSendStars.messageId) }) { - state.messages[index] = state.messages[index].withId(Message.Id(space: .remote, id: Int64(id))) + state.messages[index] = state.messages[index].withId(Message.Id(space: .remote, id: Int64(id))).withDate(Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)) } if let index = state.pinnedMessages.firstIndex(where: { $0.id == Message.Id(space: .local, id: pendingSendStars.messageId) }) { - state.pinnedMessages[index] = state.pinnedMessages[index].withId(Message.Id(space: .remote, id: Int64(id))) + state.pinnedMessages[index] = state.pinnedMessages[index].withId(Message.Id(space: .remote, id: Int64(id))).withDate(Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)) } Impl.addStateStars(state: &state, peerId: pendingSendStars.fromPeer.id, isMy: true, amount: pendingSendStars.amount) state.pendingMyStars = 0 diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift index 6a442b3de7..ddc161fc45 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelComponent.swift @@ -304,6 +304,20 @@ public final class ChatTextInputPanelComponent: Component { panelNode.ensureFocused() } + public func deactivateInput() { + guard let panelNode = self.panelNode else { + return + } + panelNode.ensureUnfocused() + } + + public var isActive: Bool { + guard let panelNode = self.panelNode else { + return false + } + return panelNode.isFocused + } + public func updateState(transition: ComponentTransition) { self.state?.updated(transition: transition) } diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift index 62a6ab63e2..c4f34a96b7 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/StarReactionButtonComponent.swift @@ -220,8 +220,10 @@ final class StarReactionButtonComponent: Component { case .ended: if let gesture = recogizer.lastRecognizedGestureAndLocation?.0 { if case .tap = gesture { + HapticFeedback().tap() component.action(self) } else if case .longTap = gesture { + HapticFeedback().impact(.medium) component.longPressAction?(self) } } diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift index a54b67f4e0..0a9fe2b676 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift @@ -764,6 +764,9 @@ public final class MessageInputPanelComponent: Component { guard let component = self.component else { return true } + if let _ = self.inputPanel?.view as? ChatTextInputPanelComponent.View { + return true + } if let maxLength = component.maxLength, self.textFieldExternalState.textLength > maxLength { return false } else { @@ -772,6 +775,9 @@ public final class MessageInputPanelComponent: Component { } public var isActive: Bool { + if let inputPanelView = self.inputPanel?.view as? ChatTextInputPanelComponent.View { + return inputPanelView.isActive + } if let textFieldView = self.textField.view as? TextFieldComponent.View { return textFieldView.isActive } else { @@ -781,6 +787,10 @@ public final class MessageInputPanelComponent: Component { public func deactivateInput(force: Bool = false) { if self.canDeactivateInput() || force { + if let inputPanelView = self.inputPanel?.view as? ChatTextInputPanelComponent.View { + inputPanelView.deactivateInput() + return + } if let textFieldView = self.textField.view as? TextFieldComponent.View { textFieldView.deactivateInput() } @@ -788,6 +798,7 @@ public final class MessageInputPanelComponent: Component { } public func animateError() { + self.inputPanel?.view?.layer.addShakeAnimation() self.textField.view?.layer.addShakeAnimation() self.hapticFeedback.error() } diff --git a/submodules/TelegramUI/Components/Stories/LiveChat/StoryLiveChatMessageComponent/Sources/StoryLiveChatMessageComponent.swift b/submodules/TelegramUI/Components/Stories/LiveChat/StoryLiveChatMessageComponent/Sources/StoryLiveChatMessageComponent.swift index 671b5ab140..6ea9cb3e48 100644 --- a/submodules/TelegramUI/Components/Stories/LiveChat/StoryLiveChatMessageComponent/Sources/StoryLiveChatMessageComponent.swift +++ b/submodules/TelegramUI/Components/Stories/LiveChat/StoryLiveChatMessageComponent/Sources/StoryLiveChatMessageComponent.swift @@ -405,6 +405,9 @@ public final class StoryLiveChatMessageComponent: Component { } var authorTitleFrame = CGRect(origin: CGPoint(x: insets.left + avatarSize + avatarSpacing, y: avatarFrame.minY + 3.0), size: authorTitleSize) + if component.layout.fitToWidth { + authorTitleFrame.origin.x += 4.0 + } if let image = self.crownIcon?.image { authorTitleFrame.origin.x += image.size.width + 4.0 } @@ -418,6 +421,9 @@ public final class StoryLiveChatMessageComponent: Component { } var textFrame = CGRect(origin: CGPoint(x: insets.left + avatarSize + avatarSpacing, y: avatarFrame.minY + 3.0), size: textSize) + if component.layout.fitToWidth { + textFrame.origin.x += 4.0 + } if component.message.isFromAdmin { textFrame.origin.y = authorTitleFrame.maxY textFrame.size.width = max(textFrame.width, authorTitleFrame.maxX - textFrame.minX) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift index 2497509730..7b6c478881 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift @@ -305,6 +305,7 @@ final class StoryContentLiveChatComponent: Component { ]) ]) + component.controller()?.view.endEditing(true) component.controller()?.present(actionSheet, in: .window(.root)) } @@ -379,12 +380,14 @@ final class StoryContentLiveChatComponent: Component { } } - private func scrollToMessage(id: GroupCallMessagesContext.Message.Id) { + @discardableResult private func scrollToMessage(id: GroupCallMessagesContext.Message.Id) -> Bool { guard let messagesState = self.messagesState, let message = messagesState.messages.first(where: { $0.id == id }) else { - return + return false } self.listState.resetScrolling(id: AnyHashable(message.stableId)) self.state?.updated(transition: .spring(duration: 0.4), isLocal: true) + + return true } private func openMessageContextMenu(id: GroupCallMessagesContext.Message.Id, isPinned: Bool, gesture: ContextGesture, sourceNode: ContextExtractedContentContainingNode) { @@ -651,7 +654,12 @@ final class StoryContentLiveChatComponent: Component { guard let self else { return } - self.scrollToMessage(id: message.id) + self.isChatExpanded = true + if !self.scrollToMessage(id: message.id) { + if !self.isUpdating { + self.state?.updated(transition: .spring(duration: 0.4)) + } + } }, contextGesture: { [weak self] message, gesture, sourceNode in guard let self else { @@ -679,7 +687,7 @@ final class StoryContentLiveChatComponent: Component { transition.setAlpha(view: pinnedBarView, alpha: pinnedBarAlpha) } - var listInsets = UIEdgeInsets(top: component.insets.bottom + 8.0, left: component.insets.right, bottom: component.insets.top + 8.0, right: component.insets.left) + var listInsets = UIEdgeInsets(top: component.insets.bottom + 12.0, left: component.insets.right, bottom: component.insets.top + 8.0, right: component.insets.left) if !topMessages.isEmpty { listInsets.top = availableSize.height - pinnedBarFrame.minY } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index 5b7bde2a57..ed883ce57d 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -464,7 +464,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { if case .liveStream = component.slice.item.storyItem.media { //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Edit Stars", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconSuggestPost"), color: theme.contextMenu.primaryColor) + items.append(.action(ContextMenuActionItem(text: self.currentLiveStreamMessageStars != nil ? "Edit Stars" : "Add Stars", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconSuggestPost"), color: theme.contextMenu.primaryColor) }, action: { [weak self, weak view] _, a in a(.default) @@ -772,7 +772,6 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { component.storyItemSharedState.replyDrafts.removeValue(forKey: StoryId(peerId: peerId, id: focusedItem.storyItem.id)) inputPanelView.clearSendMessageInput(updateState: true) - self.currentInputMode = .text self.currentLiveStreamMessageStars = nil view.state?.updated(transition: .spring(duration: 0.4))