Forum improvements

This commit is contained in:
Isaac 2025-11-11 20:05:29 +08:00
parent 89ce010de2
commit 7acf2b0b41
10 changed files with 63 additions and 36 deletions

View file

@ -51,7 +51,7 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
private let smallCircleSize: CGFloat
private let backgroundView: BlurredBackgroundView
private let glassBackgroundView: GlassBackgroundView?
private let glassBackgroundView: (container: GlassBackgroundContainerView, view: GlassBackgroundView)?
private let backgroundTintView: UIView
private let backgroundTintMaskOuterContainer: UIView
@ -77,7 +77,7 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
self.backgroundView = BlurredBackgroundView(color: nil, enableBlur: true)
if glass != nil {
self.glassBackgroundView = GlassBackgroundView()
self.glassBackgroundView = (GlassBackgroundContainerView(), GlassBackgroundView())
} else {
self.glassBackgroundView = nil
}
@ -129,8 +129,9 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
if let glassBackgroundView = self.glassBackgroundView {
self.view.addSubview(glassBackgroundView)
glassBackgroundView.addSubview(self.backgroundTintView)
glassBackgroundView.container.contentView.addSubview(glassBackgroundView.view)
self.view.addSubview(glassBackgroundView.container)
//glassBackgroundView.addSubview(self.backgroundTintView)
//glassBackgroundView.maskContentView.layer.addSublayer(self.maskLayer)
} else {
self.backgroundView.layer.mask = self.maskLayer
@ -246,14 +247,16 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
if let glassBackgroundView = self.glassBackgroundView {
var glassBackgroundFrame = contentBounds.insetBy(dx: 10.0, dy: 10.0)
glassBackgroundFrame.size.height -= 8.0
transition.updateFrame(view: glassBackgroundView, frame: glassBackgroundFrame, beginWithCurrentState: true)
transition.updateFrame(view: glassBackgroundView.container, frame: glassBackgroundFrame, beginWithCurrentState: true)
transition.updateFrame(view: glassBackgroundView.view, frame: CGRect(origin: CGPoint(), size: glassBackgroundFrame.size), beginWithCurrentState: true)
let glassTintColor: GlassBackgroundView.TintColor
if let glass = self.glass, glass.isTinted {
glassTintColor = .init(kind: .custom, color: UIColor(rgb: 0x25272e, alpha: 0.72))
} else {
glassTintColor = .init(kind: .panel, color: defaultDarkPresentationTheme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7))
}
glassBackgroundView.update(size: glassBackgroundFrame.size, cornerRadius: 23.0, isDark: true, tintColor: glassTintColor, transition: ComponentTransition(transition))
glassBackgroundView.container.update(size: glassBackgroundFrame.size, isDark: true, transition: ComponentTransition(transition))
glassBackgroundView.view.update(size: glassBackgroundFrame.size, cornerRadius: 23.0, isDark: true, tintColor: glassTintColor, transition: ComponentTransition(transition))
transition.updateFrame(view: self.backgroundTintView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentBounds.width, height: contentBounds.height)).insetBy(dx: -10.0, dy: -10.0))
} else {

View file

@ -779,10 +779,12 @@ extension StoreMessage {
}
} else if peerId.namespace == Namespaces.Peer.CloudUser, peerIsForum {
//TODO:release
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)
threadMessageId = threadIdValue
threadId = Int64(threadIdValue.id)
if isForumTopic {
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)
threadMessageId = threadIdValue
threadId = Int64(threadIdValue.id)
}
}
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, todoItemId: todoItemId))
}

View file

@ -829,7 +829,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
}
}
if threadId == nil, let peer = transaction.getPeer(peerId), peer.isForum {
if threadId == nil, let peer = transaction.getPeer(peerId), (peer is TelegramChannel), peer.isForum {
threadId = 1
}

View file

@ -82,7 +82,10 @@ private func findQuoteRange(string: String, quoteText: String, offset: Int?) ->
}
public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
private let containerNode: ASDisplayNode
public final class ContainerNode: ASDisplayNode {
}
private let containerNode: ContainerNode
private let textNode: InteractiveTextNodeWithEntities
private let textAccessibilityOverlayNode: TextAccessibilityOverlayNode
@ -159,7 +162,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
required public init() {
self.containerNode = ASDisplayNode()
self.containerNode = ContainerNode()
self.containerNode.clipsToBounds = true
self.textNode = InteractiveTextNodeWithEntities()

View file

@ -19,7 +19,7 @@ public final class ChatFloatingTopicsPanel: Component {
public let topicId: Int64?
public let controller: () -> ViewController?
public let togglePanel: () -> Void
public let updateTopicId: (Int64?, Bool) -> Void
public let updateTopicId: (Int64?, ChatControllerAnimateInnerChatSwitchDirection) -> Void
public let openDeletePeer: (Int64) -> Void
public init(
@ -32,7 +32,7 @@ public final class ChatFloatingTopicsPanel: Component {
topicId: Int64?,
controller: @escaping () -> ViewController?,
togglePanel: @escaping () -> Void,
updateTopicId: @escaping (Int64?, Bool) -> Void,
updateTopicId: @escaping (Int64?, ChatControllerAnimateInnerChatSwitchDirection) -> Void,
openDeletePeer: @escaping (Int64) -> Void
) {
self.context = context
@ -80,6 +80,8 @@ public final class ChatFloatingTopicsPanel: Component {
private var sidePanel: ComponentView<ChatSidePanelEnvironment>?
private var topPanel: ComponentView<ChatSidePanelEnvironment>?
private var component: ChatFloatingTopicsPanel?
override public init(frame: CGRect) {
self.containerView = GlassBackgroundContainerView()
@ -103,6 +105,8 @@ public final class ChatFloatingTopicsPanel: Component {
}
func update(component: ChatFloatingTopicsPanel, availableSize: CGSize, state: EmptyComponentState, environment: Environment<ChatSidePanelEnvironment>, transition: ComponentTransition) -> CGSize {
self.component = component
let environment = environment[ChatSidePanelEnvironment.self].value
var currentPanelBackgroundFrame: CGRect?
@ -129,7 +133,12 @@ public final class ChatFloatingTopicsPanel: Component {
topicId: component.topicId,
controller: component.controller,
togglePanel: component.togglePanel,
updateTopicId: component.updateTopicId,
updateTopicId: { [weak self] threadId, direction in
guard let self, let component = self.component else {
return
}
component.updateTopicId(threadId, direction ? .down : .up)
},
openDeletePeer: component.openDeletePeer
)),
environment: {
@ -187,7 +196,12 @@ public final class ChatFloatingTopicsPanel: Component {
topicId: component.topicId,
controller: component.controller,
togglePanel: component.togglePanel,
updateTopicId: component.updateTopicId,
updateTopicId: { [weak self] threadId, direction in
guard let self, let component = self.component else {
return
}
component.updateTopicId(threadId, direction ? .right : .left)
},
openDeletePeer: component.openDeletePeer
)),
environment: {

View file

@ -1242,7 +1242,6 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
if !canHandleTapAtPoint(point) {
return nil
}
guard let result = super.hitTest(point, with: event) else {
return nil
}

View file

@ -7300,7 +7300,7 @@ public final class StoryItemSetContainerComponent: Component {
})))
}
if !component.slice.item.storyItem.isForwardingDisabled {
if !component.slice.item.storyItem.isForwardingDisabled && !isLiveStream {
let saveText: String = component.strings.Story_Context_SaveToGallery
items.append(.action(ContextMenuActionItem(text: saveText, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: accountUser.isPremium ? "Chat/Context Menu/Download" : "Chat/Context Menu/DownloadLocked"), color: theme.contextMenu.primaryColor)

View file

@ -339,20 +339,23 @@ extension ChatControllerImpl {
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: strings.Conversation_ContextMenuOpenProfile, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.default)
guard let self, let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer else {
return
}
guard let controller = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
if let _ = self.chatLocation.threadId {
} else {
items.append(.action(ContextMenuActionItem(text: strings.Conversation_ContextMenuOpenProfile, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.default)
guard let self, let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer else {
return
}
(self.navigationController as? NavigationController)?.pushViewController(controller)
})))
guard let controller = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}
(self.navigationController as? NavigationController)?.pushViewController(controller)
})))
}
items.append(.separator)
items.append(.action(ContextMenuActionItem(text: strings.Conversation_Search, icon: { theme in
@ -363,7 +366,7 @@ extension ChatControllerImpl {
self?.beginMessageSearch("")
})))
if let threadId = self.chatLocation.threadId {
if let threadId = self.chatLocation.threadId, let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer, (peer is TelegramChannel || peer is TelegramGroup) {
items.append(.action(ContextMenuActionItem(text: strings.CreateTopic_EditTitle, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] action in

View file

@ -50,6 +50,7 @@ import GlassBackgroundComponent
import ChatThemeScreen
import ChatTextInputPanelNode
import ChatInputAccessoryPanel
import ChatMessageTextBubbleContentNode
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
let itemNode: OverlayMediaItemNode
@ -4090,6 +4091,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
return result
} else if let _ = node as? LinkHighlightingNode {
return result
} else if let _ = node as? ChatMessageTextBubbleContentNode.ContainerNode {
return result
}
}
}

View file

@ -244,7 +244,7 @@ func floatingTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInte
case .loading:
return nil
case let .loaded(isEmpty, _):
if isEmpty {
if isEmpty && chatPresentationInterfaceState.chatLocation.threadId == nil {
return nil
}
}
@ -267,7 +267,7 @@ func floatingTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInte
interfaceInteraction?.toggleChatSidebarMode()
},
updateTopicId: { [weak interfaceInteraction] topicId, direction in
interfaceInteraction?.updateChatLocationThread(topicId, direction ? .down : .up)
interfaceInteraction?.updateChatLocationThread(topicId, direction)
},
openDeletePeer: { [weak interfaceInteraction] threadId in
guard let controller = interfaceInteraction?.chatController() as? ChatControllerImpl else {
@ -293,7 +293,7 @@ func floatingTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInte
interfaceInteraction?.toggleChatSidebarMode()
},
updateTopicId: { [weak interfaceInteraction] topicId, direction in
interfaceInteraction?.updateChatLocationThread(topicId, direction ? .down : .up)
interfaceInteraction?.updateChatLocationThread(topicId, direction)
},
openDeletePeer: { [weak interfaceInteraction] threadId in
guard let controller = interfaceInteraction?.chatController() as? ChatControllerImpl else {
@ -319,7 +319,7 @@ func floatingTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInte
interfaceInteraction?.toggleChatSidebarMode()
},
updateTopicId: { [weak interfaceInteraction] topicId, direction in
interfaceInteraction?.updateChatLocationThread(topicId, direction ? .down : .up)
interfaceInteraction?.updateChatLocationThread(topicId, direction)
},
openDeletePeer: { [weak interfaceInteraction] threadId in
guard let controller = interfaceInteraction?.chatController() as? ChatControllerImpl else {