Various improvements

This commit is contained in:
Ilya Laktyushin 2023-11-25 17:42:18 +04:00
parent b569c0d4db
commit af9c7ed5d3
25 changed files with 190 additions and 69 deletions

View File

@ -543,6 +543,7 @@ public enum PeerInfoControllerMode {
case group(PeerId) case group(PeerId)
case reaction(MessageId) case reaction(MessageId)
case forumTopic(thread: ChatReplyThreadMessage) case forumTopic(thread: ChatReplyThreadMessage)
case recommendedChannels
} }
public enum ContactListActionItemInlineIconPosition { public enum ContactListActionItemInlineIconPosition {

View File

@ -261,9 +261,17 @@ public struct ChatControllerInitialBotAppStart {
} }
public enum ChatControllerInteractionNavigateToPeer { public enum ChatControllerInteractionNavigateToPeer {
public struct InfoParams {
public let switchToRecommendedChannels: Bool
public init(switchToRecommendedChannels: Bool) {
self.switchToRecommendedChannels = switchToRecommendedChannels
}
}
case `default` case `default`
case chat(textInputState: ChatTextInputState?, subject: ChatControllerSubject?, peekData: ChatPeekTimeout?) case chat(textInputState: ChatTextInputState?, subject: ChatControllerSubject?, peekData: ChatPeekTimeout?)
case info case info(InfoParams?)
case withBotStartPayload(ChatControllerInitialBotStart) case withBotStartPayload(ChatControllerInitialBotStart)
case withAttachBot(ChatControllerInitialAttachBotStart) case withAttachBot(ChatControllerInitialAttachBotStart)
case withBotApp(ChatControllerInitialBotAppStart) case withBotApp(ChatControllerInitialBotAppStart)

View File

@ -459,7 +459,7 @@ public final class ChatBotInfoItemNode: ListViewItemNode {
case let .peerMention(peerId, _, _): case let .peerMention(peerId, _, _):
if let item = self.item { if let item = self.item {
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
if let peer = peer { if let peer = peer {
self?.item?.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) self?.item?.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} }

View File

@ -430,7 +430,7 @@ public final class ChatButtonKeyboardInputNode: ChatInputNode {
guard let self, let peer else { guard let self, let peer else {
return return
} }
self.controllerInteraction.openPeer(peer, .info, nil, .default) self.controllerInteraction.openPeer(peer, .info(nil), nil, .default)
}) })
case let .openWebView(url, simple): case let .openWebView(url, simple):
self.controllerInteraction.openWebView(markupButton.title, url, simple, .generic) self.controllerInteraction.openWebView(markupButton.title, url, simple, .generic)

View File

@ -2072,7 +2072,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} }
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil)) item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil))
} else if let peer = forwardInfo.source ?? forwardInfo.author { } else if let peer = forwardInfo.source ?? forwardInfo.author {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} else if let _ = forwardInfo.authorSignature { } else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
} }

View File

@ -4244,7 +4244,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
} }
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil)) item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil))
} else if let peer = forwardInfo.source ?? forwardInfo.author { } else if let peer = forwardInfo.source ?? forwardInfo.author {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} else if let _ = forwardInfo.authorSignature { } else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
} }
@ -4264,7 +4264,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
} else { } else {
if let peer = item.message.peers[story.storyId.peerId] { if let peer = item.message.peers[story.storyId.peerId] {
return .action(InternalBubbleTapAction.Action { return .action(InternalBubbleTapAction.Action {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
}) })
} }
} }
@ -4318,7 +4318,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { peer in |> deliverOnMainQueue).startStandalone(next: { peer in
if let self = self, let item = self.item, let peer = peer { if let self = self, let item = self.item, let peer = peer {
item.controllerInteraction.openPeer(peer, openProfile ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(peer, openProfile ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} }
}) })
} }
@ -4983,7 +4983,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let channel = peer as? TelegramChannel, case .broadcast = channel.info { if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), messageReference, .default) item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), messageReference, .default)
} else { } else {
item.controllerInteraction.openPeer(EnginePeer(peer), .info, messageReference, .groupParticipant(storyStats: nil, avatarHeaderNode: nil)) item.controllerInteraction.openPeer(EnginePeer(peer), .info(nil), messageReference, .groupParticipant(storyStats: nil, avatarHeaderNode: nil))
} }
} }
} }

View File

@ -988,7 +988,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco
} }
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil)) item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil))
} else if let peer = forwardInfo.source ?? forwardInfo.author { } else if let peer = forwardInfo.source ?? forwardInfo.author {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} else if let _ = forwardInfo.authorSignature { } else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
} }

View File

@ -1379,7 +1379,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil)) item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil))
return return
} else if let peer = forwardInfo.source ?? forwardInfo.author { } else if let peer = forwardInfo.source ?? forwardInfo.author {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
return return
} else if let _ = forwardInfo.authorSignature { } else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)

View File

@ -735,7 +735,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat
if let channel = peer as? TelegramChannel, case .broadcast = channel.info { if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, .default) self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, .default)
} else { } else {
self.controllerInteraction.openPeer(EnginePeer(peer), .info, self.messageReference, .groupParticipant(storyStats: nil, avatarHeaderNode: self)) self.controllerInteraction.openPeer(EnginePeer(peer), .info(nil), self.messageReference, .groupParticipant(storyStats: nil, avatarHeaderNode: self))
} }
} }
} }

View File

@ -823,7 +823,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol {
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { peer in |> deliverOnMainQueue).startStandalone(next: { peer in
if let peer = peer { if let peer = peer {
item.controllerInteraction.openPeer(peer, .info, nil, .default) item.controllerInteraction.openPeer(peer, .info(nil), nil, .default)
} }
}) })
case let .openWebView(url, simple): case let .openWebView(url, simple):

View File

@ -357,8 +357,21 @@ public class ChatMessageJoinedChannelBubbleContentNode: ChatMessageBubbleContent
item.controllerInteraction.presentControllerInCurrent(controller, nil) item.controllerInteraction.presentControllerInCurrent(controller, nil)
} }
}, },
contextAction: { peer, sourceView, gesture in openMore: { [weak self] in
item.controllerInteraction.openRecommendedChannelContextMenu(peer, sourceView, gesture) guard let item = self?.item else {
return
}
let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: item.message.id.peerId))
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
if let peer = peer {
self?.item?.controllerInteraction.openPeer(peer, .info(ChatControllerInteractionNavigateToPeer.InfoParams(switchToRecommendedChannels: true)), nil, .default)
}
})
},
contextAction: { [weak self] peer, sourceView, gesture in
if let item = self?.item {
item.controllerInteraction.openRecommendedChannelContextMenu(peer, sourceView, gesture)
}
} }
) )
), ),
@ -531,6 +544,11 @@ private class MessageBackgroundNode: ASDisplayNode {
private let itemSize = CGSize(width: 84.0, height: 90.0) private let itemSize = CGSize(width: 84.0, height: 90.0)
private final class ChannelItemComponent: Component { private final class ChannelItemComponent: Component {
class ExternalState {
var cachedPlaceholderImage: UIImage?
}
let externalState: ExternalState
let context: AccountContext let context: AccountContext
let theme: PresentationTheme let theme: PresentationTheme
let strings: PresentationStrings let strings: PresentationStrings
@ -539,9 +557,11 @@ private final class ChannelItemComponent: Component {
let title: String let title: String
let subtitle: String let subtitle: String
let action: (EnginePeer?) -> Void let action: (EnginePeer?) -> Void
let openMore: () -> Void
let contextAction: ((EnginePeer, UIView, ContextGesture?) -> Void)? let contextAction: ((EnginePeer, UIView, ContextGesture?) -> Void)?
init( init(
externalState: ExternalState,
context: AccountContext, context: AccountContext,
theme: PresentationTheme, theme: PresentationTheme,
strings: PresentationStrings, strings: PresentationStrings,
@ -550,8 +570,10 @@ private final class ChannelItemComponent: Component {
title: String, title: String,
subtitle: String, subtitle: String,
action: @escaping (EnginePeer?) -> Void, action: @escaping (EnginePeer?) -> Void,
openMore: @escaping () -> Void,
contextAction: ((EnginePeer, UIView, ContextGesture?) -> Void)? contextAction: ((EnginePeer, UIView, ContextGesture?) -> Void)?
) { ) {
self.externalState = externalState
self.context = context self.context = context
self.theme = theme self.theme = theme
self.strings = strings self.strings = strings
@ -560,6 +582,7 @@ private final class ChannelItemComponent: Component {
self.title = title self.title = title
self.subtitle = subtitle self.subtitle = subtitle
self.action = action self.action = action
self.openMore = openMore
self.contextAction = contextAction self.contextAction = contextAction
} }
@ -592,8 +615,7 @@ private final class ChannelItemComponent: Component {
private let title = ComponentView<Empty>() private let title = ComponentView<Empty>()
private let subtitle = ComponentView<Empty>() private let subtitle = ComponentView<Empty>()
private let circleView: UIImageView private let circlesView: UIImageView
private let circleView2: UIImageView
private let avatarNode: AvatarNode private let avatarNode: AvatarNode
private var mergedAvatarsNode: MergedAvatarsNode? private var mergedAvatarsNode: MergedAvatarsNode?
@ -606,16 +628,7 @@ private final class ChannelItemComponent: Component {
override init(frame: CGRect) { override init(frame: CGRect) {
self.contextContainer = ContextControllerSourceView() self.contextContainer = ContextControllerSourceView()
self.circleView = UIImageView(image: UIImage(bundleImageName: "Avatar/SampleAvatar1")) self.circlesView = UIImageView()
self.circleView.clipsToBounds = true
self.circleView.layer.cornerRadius = 30
self.circleView.clipsToBounds = true
self.circleView.layer.cornerRadius = 30
let colors: NSArray = [UIColor(rgb: 0x000000).cgColor, UIColor(rgb: 0x6a2267).cgColor]
self.circleView2 = UIImageView(image: generateGradientFilledCircleImage(diameter: 60, colors: colors))
self.circleView2.clipsToBounds = true
self.circleView2.layer.cornerRadius = 30
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 26.0)) self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 26.0))
self.avatarNode.isUserInteractionEnabled = false self.avatarNode.isUserInteractionEnabled = false
@ -630,8 +643,6 @@ private final class ChannelItemComponent: Component {
self.contextContainer.addSubview(self.containerButton) self.contextContainer.addSubview(self.containerButton)
self.contextContainer.addSubview(self.circleView2)
self.contextContainer.addSubview(self.circleView)
self.contextContainer.addSubnode(self.avatarNode) self.contextContainer.addSubnode(self.avatarNode)
self.contextContainer.addSubview(self.avatarBadge) self.contextContainer.addSubview(self.avatarBadge)
@ -655,7 +666,11 @@ private final class ChannelItemComponent: Component {
return return
} }
if !component.isLocked { if !component.isLocked {
component.action(peer) if component.peers.count > 1 {
component.openMore()
} else {
component.action(peer)
}
} else { } else {
component.action(nil) component.action(nil)
} }
@ -739,6 +754,7 @@ private final class ChannelItemComponent: Component {
mergedAvatarsNode = current mergedAvatarsNode = current
} else { } else {
mergedAvatarsNode = MergedAvatarsNode() mergedAvatarsNode = MergedAvatarsNode()
mergedAvatarsNode.isUserInteractionEnabled = false
self.contextContainer.insertSubview(mergedAvatarsNode.view, aboveSubview: self.avatarNode.view) self.contextContainer.insertSubview(mergedAvatarsNode.view, aboveSubview: self.avatarNode.view)
self.mergedAvatarsNode = mergedAvatarsNode self.mergedAvatarsNode = mergedAvatarsNode
} }
@ -755,14 +771,80 @@ private final class ChannelItemComponent: Component {
} }
if component.isLocked { if component.isLocked {
self.circleView.isHidden = false if self.circlesView.superview == nil {
self.circleView.frame = avatarFrame.offsetBy(dx: 10.0, dy: 0.0) self.contextContainer.insertSubview(self.circlesView, belowSubview: self.avatarNode.view)
self.circleView2.frame = avatarFrame.offsetBy(dx: 20.0, dy: 0.0) }
self.circlesView.isHidden = false
self.circleView2.isHidden = false if self.circlesView.image == nil {
if let current = component.externalState.cachedPlaceholderImage {
self.circlesView.image = current
} else {
let image = generateImage(CGSize(width: 50.0, height: avatarSize.height), rotatedContext: { size, context in
context.clear(CGRect(origin: .zero, size: size))
let randomColors: [(UInt32, UInt32)] = [
(0x4493de, 0x52d5d9),
(0xfcc418, 0xf6774a),
(0xffc9a2, 0xfbedb2),
(0x133e88, 0x131925),
(0x63c7f0, 0xf6c506),
(0x88a5cb, 0x162639),
(0xd669ed, 0xe0a2f3),
(0x54cb68, 0xa0de7e)
]
context.saveGState()
let rect1 = CGRect(origin: CGPoint(x: size.width - avatarSize.width, y: 0.0), size: avatarSize)
context.addEllipse(in: rect1)
context.clip()
var firstColors: NSArray = []
if let random = randomColors.randomElement() {
firstColors = [UIColor(rgb: random.0).cgColor, UIColor(rgb: random.1).cgColor]
}
var locations: [CGFloat] = [1.0, 0.0]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let firstGradient = CGGradient(colorsSpace: colorSpace, colors: firstColors as CFArray, locations: &locations)!
context.drawLinearGradient(firstGradient, start: CGPoint(x: rect1.minX, y: rect1.minY), end: CGPoint(x: rect1.maxX, y: rect1.maxY), options: CGGradientDrawingOptions())
context.restoreGState()
context.setBlendMode(.clear)
context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - avatarSize.width - 12.0, y: -2.0), size: CGSize(width: avatarSize.width + 4.0, height: avatarSize.height + 4.0)))
context.setBlendMode(.normal)
context.saveGState()
let rect2 = CGRect(origin: CGPoint(x: size.width - avatarSize.width - 10.0, y: 0.0), size: avatarSize)
context.addEllipse(in: rect2)
context.clip()
var secondColors: NSArray = []
if let random = randomColors.randomElement() {
secondColors = [UIColor(rgb: random.0).cgColor, UIColor(rgb: random.1).cgColor]
}
let secondGradient = CGGradient(colorsSpace: colorSpace, colors: secondColors as CFArray, locations: &locations)!
context.drawLinearGradient(secondGradient, start: CGPoint(x: rect2.minX, y: rect2.minY), end: CGPoint(x: rect2.minX, y: rect2.maxY), options: CGGradientDrawingOptions())
context.restoreGState()
context.setBlendMode(.clear)
context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - avatarSize.width - 22.0, y: -2.0), size: CGSize(width: avatarSize.width + 4.0, height: avatarSize.height + 4.0)))
})
component.externalState.cachedPlaceholderImage = image
self.circlesView.image = image
}
}
self.circlesView.frame = CGRect(origin: CGPoint(x: avatarFrame.midX, y: 0.0), size: CGSize(width: 50.0, height: 60.0))
} else { } else {
self.circleView.isHidden = true if self.circlesView.superview != nil {
self.circleView2.isHidden = true self.circlesView.removeFromSuperview()
}
} }
if let titleView = self.title.view { if let titleView = self.title.view {
@ -821,6 +903,7 @@ final class ChannelListPanelComponent: Component {
let strings: PresentationStrings let strings: PresentationStrings
let peers: RecommendedChannels let peers: RecommendedChannels
let action: (EnginePeer?) -> Void let action: (EnginePeer?) -> Void
let openMore: () -> Void
let contextAction: (EnginePeer, UIView, ContextGesture?) -> Void let contextAction: (EnginePeer, UIView, ContextGesture?) -> Void
init( init(
@ -829,6 +912,7 @@ final class ChannelListPanelComponent: Component {
strings: PresentationStrings, strings: PresentationStrings,
peers: RecommendedChannels, peers: RecommendedChannels,
action: @escaping (EnginePeer?) -> Void, action: @escaping (EnginePeer?) -> Void,
openMore: @escaping () -> Void,
contextAction: @escaping (EnginePeer, UIView, ContextGesture?) -> Void contextAction: @escaping (EnginePeer, UIView, ContextGesture?) -> Void
) { ) {
self.context = context self.context = context
@ -836,6 +920,7 @@ final class ChannelListPanelComponent: Component {
self.strings = strings self.strings = strings
self.peers = peers self.peers = peers
self.action = action self.action = action
self.openMore = openMore
self.contextAction = contextAction self.contextAction = contextAction
} }
@ -906,6 +991,7 @@ final class ChannelListPanelComponent: Component {
private let measureItem = ComponentView<Empty>() private let measureItem = ComponentView<Empty>()
private var visibleItems: [EnginePeer.Id: ComponentView<Empty>] = [:] private var visibleItems: [EnginePeer.Id: ComponentView<Empty>] = [:]
private var externalState = ChannelItemComponent.ExternalState()
private var ignoreScrolling: Bool = false private var ignoreScrolling: Bool = false
@ -1006,6 +1092,7 @@ final class ChannelListPanelComponent: Component {
let _ = itemView.update( let _ = itemView.update(
transition: itemTransition, transition: itemTransition,
component: AnyComponent(ChannelItemComponent( component: AnyComponent(ChannelItemComponent(
externalState: self.externalState,
context: component.context, context: component.context,
theme: component.theme, theme: component.theme,
strings: component.strings, strings: component.strings,
@ -1014,6 +1101,7 @@ final class ChannelListPanelComponent: Component {
title: title, title: title,
subtitle: subtitle, subtitle: subtitle,
action: component.action, action: component.action,
openMore: component.openMore,
contextAction: !isLocked && peers.count == 1 ? component.contextAction : nil contextAction: !isLocked && peers.count == 1 ? component.contextAction : nil
)), )),
environment: {}, environment: {},

View File

@ -1400,7 +1400,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
} }
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil)) item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId, NavigateToMessageParams(timestamp: nil, quote: nil))
} else if let peer = forwardInfo.source ?? forwardInfo.author { } else if let peer = forwardInfo.source ?? forwardInfo.author {
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info(nil) : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
} else if let _ = forwardInfo.authorSignature { } else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
} }

View File

@ -2,7 +2,7 @@ import Foundation
import UIKit import UIKit
public enum ChatNavigationButtonAction: Equatable { public enum ChatNavigationButtonAction: Equatable {
case openChatInfo(expandAvatar: Bool) case openChatInfo(expandAvatar: Bool, recommendedChannels: Bool)
case clearHistory case clearHistory
case clearCache case clearCache
case cancelMessageSelection case cancelMessageSelection

View File

@ -212,6 +212,14 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
} }
} }
public var hidesOnLock: Bool = false {
didSet {
if self.hidesOnLock {
self.setHidesPanelOnLock()
}
}
}
private func updateShadow() { private func updateShadow() {
if let view = self.animationView.view { if let view = self.animationView.view {
if self.hasShadow { if self.hasShadow {
@ -340,8 +348,6 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
self.updateMode(mode: self.mode, animated: false, force: true) self.updateMode(mode: self.mode, animated: false, force: true)
self.setHidesPanelOnLock()
self.delegate = self self.delegate = self
self.isExclusiveTouch = false; self.isExclusiveTouch = false;

View File

@ -599,6 +599,7 @@ public final class MessageInputActionButtonComponent: Component {
if let micButton = self.micButton { if let micButton = self.micButton {
micButton.hasShadow = component.hasShadow micButton.hasShadow = component.hasShadow
micButton.hidesOnLock = component.hasShadow
if themeUpdated { if themeUpdated {
micButton.updateTheme(theme: defaultDarkPresentationTheme) micButton.updateTheme(theme: defaultDarkPresentationTheme)

View File

@ -498,13 +498,16 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
private var currentAvailablePanes: [PeerInfoPaneKey]? private var currentAvailablePanes: [PeerInfoPaneKey]?
private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, isMediaOnly: Bool) { private let initialPaneKey: PeerInfoPaneKey?
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, isMediaOnly: Bool, initialPaneKey: PeerInfoPaneKey?) {
self.context = context self.context = context
self.updatedPresentationData = updatedPresentationData self.updatedPresentationData = updatedPresentationData
self.peerId = peerId self.peerId = peerId
self.chatLocation = chatLocation self.chatLocation = chatLocation
self.chatLocationContextHolder = chatLocationContextHolder self.chatLocationContextHolder = chatLocationContextHolder
self.isMediaOnly = isMediaOnly self.isMediaOnly = isMediaOnly
self.initialPaneKey = initialPaneKey
self.additionalBackgroundNode = ASDisplayNode() self.additionalBackgroundNode = ASDisplayNode()
@ -730,7 +733,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
self.pendingSwitchToPaneKey = nil self.pendingSwitchToPaneKey = nil
} }
} else if self.currentPaneKey == nil { } else if self.currentPaneKey == nil {
self.pendingSwitchToPaneKey = availablePanes.first self.pendingSwitchToPaneKey = self.initialPaneKey ?? availablePanes.first
} }
let currentIndex: Int? let currentIndex: Int?
@ -785,13 +788,13 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
} }
for key in requiredPendingKeys { for key in requiredPendingKeys {
if self.pendingPanes[key] == nil { if self.pendingPanes[key] == nil, let data {
var leftScope = false var leftScope = false
let pane = PeerInfoPendingPane( let pane = PeerInfoPendingPane(
context: self.context, context: self.context,
updatedPresentationData: self.updatedPresentationData, updatedPresentationData: self.updatedPresentationData,
chatControllerInteraction: self.chatControllerInteraction!, chatControllerInteraction: self.chatControllerInteraction!,
data: data!, data: data,
openPeerContextAction: { [weak self] recommended, peer, node, gesture in openPeerContextAction: { [weak self] recommended, peer, node, gesture in
self?.openPeerContextAction?(recommended, peer, node, gesture) self?.openPeerContextAction?(recommended, peer, node, gesture)
}, },

View File

@ -2233,7 +2233,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
} }
private var didSetReady = false private var didSetReady = false
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>) { init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, initialPaneKey: PeerInfoPaneKey?) {
self.controller = controller self.controller = controller
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
@ -2257,7 +2257,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
forumTopicThreadId = Int64(message.messageId.id) forumTopicThreadId = Int64(message.messageId.id)
} }
self.headerNode = PeerInfoHeaderNode(context: context, controller: controller, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, isMediaOnly: self.isMediaOnly, isSettings: isSettings, forumTopicThreadId: forumTopicThreadId, chatLocation: self.chatLocation) self.headerNode = PeerInfoHeaderNode(context: context, controller: controller, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, isMediaOnly: self.isMediaOnly, isSettings: isSettings, forumTopicThreadId: forumTopicThreadId, chatLocation: self.chatLocation)
self.paneContainerNode = PeerInfoPaneContainerNode(context: context, updatedPresentationData: controller.updatedPresentationData, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, isMediaOnly: self.isMediaOnly) self.paneContainerNode = PeerInfoPaneContainerNode(context: context, updatedPresentationData: controller.updatedPresentationData, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, isMediaOnly: self.isMediaOnly, initialPaneKey: initialPaneKey)
super.init() super.init()
@ -9138,7 +9138,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
} }
} else if let currentPaneKey = self.paneContainerNode.currentPaneKey, case .members = currentPaneKey { } else if let currentPaneKey = self.paneContainerNode.currentPaneKey, case .members = currentPaneKey {
self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .list, placeholder: self.presentationData.strings.Common_Search, hasBackground: true, hasSeparator: true, contentNode: ChannelMembersSearchContainerNode(context: self.context, forceTheme: nil, peerId: self.peerId, mode: .searchMembers, filters: [], searchContext: self.groupMembersSearchContext, openPeer: { [weak self] peer, participant in self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .list, placeholder: self.presentationData.strings.Common_Search, hasBackground: true, hasSeparator: true, contentNode: ChannelMembersSearchContainerNode(context: self.context, forceTheme: nil, peerId: self.peerId, mode: .searchMembers, filters: [], searchContext: self.groupMembersSearchContext, openPeer: { [weak self] peer, participant in
self?.openPeer(peerId: peer.id, navigation: .info) self?.openPeer(peerId: peer.id, navigation: .info(nil))
}, updateActivity: { _ in }, updateActivity: { _ in
}, pushController: { [weak self] c in }, pushController: { [weak self] c in
self?.controller?.push(c) self?.controller?.push(c)
@ -10283,6 +10283,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
private let isSettings: Bool private let isSettings: Bool
private let hintGroupInCommon: PeerId? private let hintGroupInCommon: PeerId?
private weak var requestsContext: PeerInvitationImportersContext? private weak var requestsContext: PeerInvitationImportersContext?
private let switchToRecommendedChannels: Bool
private let chatLocation: ChatLocation private let chatLocation: ChatLocation
private let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil) private let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil)
@ -10331,7 +10332,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
private var validLayout: (layout: ContainerViewLayout, navigationHeight: CGFloat)? private var validLayout: (layout: ContainerViewLayout, navigationHeight: CGFloat)?
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool = false, hintGroupInCommon: PeerId? = nil, requestsContext: PeerInvitationImportersContext? = nil, forumTopicThread: ChatReplyThreadMessage? = nil) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool = false, hintGroupInCommon: PeerId? = nil, requestsContext: PeerInvitationImportersContext? = nil, forumTopicThread: ChatReplyThreadMessage? = nil, switchToRecommendedChannels: Bool = false) {
self.context = context self.context = context
self.updatedPresentationData = updatedPresentationData self.updatedPresentationData = updatedPresentationData
self.peerId = peerId self.peerId = peerId
@ -10343,6 +10344,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
self.isSettings = isSettings self.isSettings = isSettings
self.hintGroupInCommon = hintGroupInCommon self.hintGroupInCommon = hintGroupInCommon
self.requestsContext = requestsContext self.requestsContext = requestsContext
self.switchToRecommendedChannels = switchToRecommendedChannels
if let forumTopicThread = forumTopicThread { if let forumTopicThread = forumTopicThread {
self.chatLocation = .replyThread(message: forumTopicThread) self.chatLocation = .replyThread(message: forumTopicThread)
@ -10659,7 +10661,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
} }
override public func loadDisplayNode() { override public func loadDisplayNode() {
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder) self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, initialPaneKey: self.switchToRecommendedChannels ? .recommended : nil)
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 }) self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get()) self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get()) self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())

View File

@ -2798,7 +2798,7 @@ final class StoryItemSetContainerSendMessage {
if let peer = peer { if let peer = peer {
var navigation: ChatControllerInteractionNavigateToPeer var navigation: ChatControllerInteractionNavigateToPeer
if let peer = peer as? TelegramUser, peer.botInfo == nil { if let peer = peer as? TelegramUser, peer.botInfo == nil {
navigation = .info navigation = .info(nil)
} else { } else {
navigation = .chat(textInputState: nil, subject: nil, peekData: nil) navigation = .chat(textInputState: nil, subject: nil, peekData: nil)
} }

View File

@ -3607,7 +3607,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.actionSheet.primaryTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
self?.openPeer(peer: peer, navigation: .info, fromMessage: nil) self?.openPeer(peer: peer, navigation: .info(nil), fromMessage: nil)
})) }))
] ]
items.append(.action(ContextMenuActionItem(text: isChannel ? strongSelf.presentationData.strings.Conversation_ContextMenuOpenChannel : strongSelf.presentationData.strings.Conversation_ContextMenuSendMessage, icon: { theme in items.append(.action(ContextMenuActionItem(text: isChannel ? strongSelf.presentationData.strings.Conversation_ContextMenuOpenChannel : strongSelf.presentationData.strings.Conversation_ContextMenuSendMessage, icon: { theme in
@ -4744,7 +4744,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
self?.navigationButtonAction(.openChatInfo(expandAvatar: true)) self?.navigationButtonAction(.openChatInfo(expandAvatar: true, recommendedChannels: false))
})) }))
] ]
if canViewStats { if canViewStats {
@ -4793,7 +4793,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
chatInfoButtonItem.target = self chatInfoButtonItem.target = self
chatInfoButtonItem.action = #selector(self.rightNavigationButtonAction) chatInfoButtonItem.action = #selector(self.rightNavigationButtonAction)
self.chatInfoNavigationButton = ChatNavigationButton(action: .openChatInfo(expandAvatar: true), buttonItem: chatInfoButtonItem) self.chatInfoNavigationButton = ChatNavigationButton(action: .openChatInfo(expandAvatar: true, recommendedChannels: false), buttonItem: chatInfoButtonItem)
self.moreBarButton.setContent(.more(MoreHeaderButton.optionsCircleImage(color: self.presentationData.theme.rootController.navigationBar.buttonColor))) self.moreBarButton.setContent(.more(MoreHeaderButton.optionsCircleImage(color: self.presentationData.theme.rootController.navigationBar.buttonColor)))
self.moreInfoNavigationButton = ChatNavigationButton(action: .toggleInfoPanel, buttonItem: UIBarButtonItem(customDisplayNode: self.moreBarButton)!) self.moreInfoNavigationButton = ChatNavigationButton(action: .toggleInfoPanel, buttonItem: UIBarButtonItem(customDisplayNode: self.moreBarButton)!)
@ -4810,7 +4810,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.navigationItem.titleView = self.chatTitleView self.navigationItem.titleView = self.chatTitleView
self.chatTitleView?.pressed = { [weak self] in self.chatTitleView?.pressed = { [weak self] in
self?.navigationButtonAction(.openChatInfo(expandAvatar: false)) self?.navigationButtonAction(.openChatInfo(expandAvatar: false, recommendedChannels: false))
} }
self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in
@ -9057,7 +9057,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
}) })
}, openPeerInfo: { [weak self] in }, openPeerInfo: { [weak self] in
self?.navigationButtonAction(.openChatInfo(expandAvatar: false)) self?.navigationButtonAction(.openChatInfo(expandAvatar: false, recommendedChannels: false))
}, togglePeerNotifications: { [weak self] in }, togglePeerNotifications: { [weak self] in
if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId { if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId {
let _ = strongSelf.context.engine.peers.togglePeerMuted(peerId: peerId, threadId: strongSelf.chatLocation.threadId).startStandalone() let _ = strongSelf.context.engine.peers.togglePeerMuted(peerId: peerId, threadId: strongSelf.chatLocation.threadId).startStandalone()
@ -11878,7 +11878,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
@objc func rightNavigationButtonAction() { @objc func rightNavigationButtonAction() {
if let button = self.rightNavigationButton { if let button = self.rightNavigationButton {
if case let .peer(peerId) = self.chatLocation, case .openChatInfo(expandAvatar: true) = button.action, let storyStats = self.storyStats, storyStats.unseenCount != 0, let avatarNode = self.avatarNode { if case let .peer(peerId) = self.chatLocation, case .openChatInfo(expandAvatar: true, _) = button.action, let storyStats = self.storyStats, storyStats.unseenCount != 0, let avatarNode = self.avatarNode {
self.openStories(peerId: peerId, avatarHeaderNode: nil, avatarNode: avatarNode.avatarNode) self.openStories(peerId: peerId, avatarHeaderNode: nil, avatarNode: avatarNode.avatarNode)
} else { } else {
self.navigationButtonAction(button.action) self.navigationButtonAction(button.action)
@ -12186,7 +12186,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.present(actionSheet, in: .window(.root)) strongSelf.present(actionSheet, in: .window(.root))
}) })
} }
case let .openChatInfo(expandAvatar): case let .openChatInfo(expandAvatar, recommendedChannels):
let _ = self.presentVoiceMessageDiscardAlert(action: { let _ = self.presentVoiceMessageDiscardAlert(action: {
switch self.chatLocationInfoData { switch self.chatLocationInfoData {
case let .peer(peerView): case let .peer(peerView):
@ -12206,7 +12206,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let validLayout = strongSelf.validLayout, validLayout.deviceMetrics.type == .tablet { if let validLayout = strongSelf.validLayout, validLayout.deviceMetrics.type == .tablet {
expandAvatar = false expandAvatar = false
} }
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: strongSelf.inviteRequestsContext) { if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: recommendedChannels ? .recommendedChannels : .generic, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: strongSelf.inviteRequestsContext) {
strongSelf.effectiveNavigationController?.pushViewController(infoController) strongSelf.effectiveNavigationController?.pushViewController(infoController)
} }
} }
@ -12736,7 +12736,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
openBotApp(allowWrite, false) openBotApp(allowWrite, false)
}, showMore: { [weak self] in }, showMore: { [weak self] in
if let self { if let self {
self.openResolved(result: .peer(botPeer._asPeer(), .info), sourceMessageId: nil) self.openResolved(result: .peer(botPeer._asPeer(), .info(nil)), sourceMessageId: nil)
} }
}) })
self.present(controller, in: .window(.root)) self.present(controller, in: .window(.root))
@ -16343,8 +16343,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let _ = self.presentVoiceMessageDiscardAlert(action: { let _ = self.presentVoiceMessageDiscardAlert(action: {
if case let .peer(currentPeerId) = self.chatLocation, peer?.id == currentPeerId { if case let .peer(currentPeerId) = self.chatLocation, peer?.id == currentPeerId {
switch navigation { switch navigation {
case .info: case let .info(params):
self.navigationButtonAction(.openChatInfo(expandAvatar: expandAvatar)) var recommendedChannels = false
if let params, params.switchToRecommendedChannels {
recommendedChannels = true
}
self.navigationButtonAction(.openChatInfo(expandAvatar: expandAvatar, recommendedChannels: recommendedChannels))
case let .chat(textInputState, _, _): case let .chat(textInputState, _, _):
if let textInputState = textInputState { if let textInputState = textInputState {
self.updateChatPresentationInterfaceState(animated: true, interactive: true, { self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
@ -16393,6 +16397,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let fromReactionMessageId = fromReactionMessageId { if let fromReactionMessageId = fromReactionMessageId {
mode = .reaction(fromReactionMessageId) mode = .reaction(fromReactionMessageId)
} }
if case let .info(params) = navigation, let params, params.switchToRecommendedChannels {
mode = .recommendedChannels
}
var expandAvatar = expandAvatar var expandAvatar = expandAvatar
if peer.smallProfileImage == nil { if peer.smallProfileImage == nil {
expandAvatar = false expandAvatar = false

View File

@ -920,7 +920,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { peer in |> deliverOnMainQueue).startStandalone(next: { peer in
if let peer = peer { if let peer = peer {
controllerInteraction.openPeer(peer, .info, nil, .default) controllerInteraction.openPeer(peer, .info(nil), nil, .default)
} }
}) })
case let .openWebView(url, simple): case let .openWebView(url, simple):

View File

@ -173,7 +173,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
}, stopLiveLocation: { messageId in }, stopLiveLocation: { messageId in
params.context.liveLocationManager?.cancelLiveLocation(peerId: messageId?.peerId ?? params.message.id.peerId) params.context.liveLocationManager?.cancelLiveLocation(peerId: messageId?.peerId ?? params.message.id.peerId)
}, openUrl: params.openUrl, openPeer: { peer in }, openUrl: params.openUrl, openPeer: { peer in
params.openPeer(peer._asPeer(), .info) params.openPeer(peer._asPeer(), .info(nil))
}, showAll: params.modal) }, showAll: params.modal)
let controller = LocationViewController(context: params.context, updatedPresentationData: params.updatedPresentationData, subject: EngineMessage(params.message), params: controllerParams) let controller = LocationViewController(context: params.context, updatedPresentationData: params.updatedPresentationData, subject: EngineMessage(params.message), params: controllerParams)
controller.navigationPresentation = .modal controller.navigationPresentation = .modal

View File

@ -41,7 +41,7 @@ private func defaultNavigationForPeerId(_ peerId: PeerId?, navigation: ChatContr
return .chat(textInputState: nil, subject: nil, peekData: nil) return .chat(textInputState: nil, subject: nil, peekData: nil)
} }
} else { } else {
return .info return .info(nil)
} }
} else { } else {
return navigation return navigation

View File

@ -1899,18 +1899,22 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: []) return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [])
} else if let _ = peer as? TelegramChannel { } else if let _ = peer as? TelegramChannel {
var forumTopicThread: ChatReplyThreadMessage? var forumTopicThread: ChatReplyThreadMessage?
var switchToRecommendedChannels = false
switch mode { switch mode {
case let .forumTopic(thread): case let .forumTopic(thread):
forumTopicThread = thread forumTopicThread = thread
case .recommendedChannels:
switchToRecommendedChannels = true
default: default:
break break
} }
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [], forumTopicThread: forumTopicThread) return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [], forumTopicThread: forumTopicThread, switchToRecommendedChannels: switchToRecommendedChannels)
} else if peer is TelegramUser { } else if peer is TelegramUser {
var nearbyPeerDistance: Int32? var nearbyPeerDistance: Int32?
var reactionSourceMessageId: MessageId? var reactionSourceMessageId: MessageId?
var callMessages: [Message] = [] var callMessages: [Message] = []
var hintGroupInCommon: PeerId? var hintGroupInCommon: PeerId?
switch mode { switch mode {
case let .nearbyPeer(distance): case let .nearbyPeer(distance):
nearbyPeerDistance = distance nearbyPeerDistance = distance
@ -1924,6 +1928,8 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
reactionSourceMessageId = messageId reactionSourceMessageId = messageId
case .forumTopic: case .forumTopic:
break break
default:
break
} }
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, reactionSourceMessageId: reactionSourceMessageId, callMessages: callMessages, hintGroupInCommon: hintGroupInCommon) return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, reactionSourceMessageId: reactionSourceMessageId, callMessages: callMessages, hintGroupInCommon: hintGroupInCommon)
} else if peer is TelegramSecretChat { } else if peer is TelegramSecretChat {

View File

@ -620,7 +620,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
return .single(.result(.peer(peer, .chat(textInputState: nil, subject: nil, peekData: nil)))) return .single(.result(.peer(peer, .chat(textInputState: nil, subject: nil, peekData: nil))))
} }
} else { } else {
return .single(.result(.peer(nil, .info))) return .single(.result(.peer(nil, .info(nil))))
} }
} }
case let .peer(reference, parameter): case let .peer(reference, parameter):
@ -780,7 +780,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil)))) return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))))
} }
} else { } else {
return .single(.result(.peer(nil, .info))) return .single(.result(.peer(nil, .info(nil))))
} }
} }
case let .peerId(peerId): case let .peerId(peerId):
@ -796,9 +796,9 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
return .single(.progress) |> then(context.engine.peers.importContactToken(token: token) return .single(.progress) |> then(context.engine.peers.importContactToken(token: token)
|> mapToSignal { peer -> Signal<ResolveInternalUrlResult, NoError> in |> mapToSignal { peer -> Signal<ResolveInternalUrlResult, NoError> in
if let peer = peer { if let peer = peer {
return .single(.result(.peer(peer._asPeer(), .info))) return .single(.result(.peer(peer._asPeer(), .info(nil))))
} else { } else {
return .single(.result(.peer(nil, .info))) return .single(.result(.peer(nil, .info(nil))))
} }
}) })
case let .privateMessage(messageId, threadId, timecode): case let .privateMessage(messageId, threadId, timecode):