Monoforums

This commit is contained in:
Isaac 2025-05-26 23:38:55 +08:00
parent cf5223ab46
commit 60f2b98ee8
5 changed files with 130 additions and 12 deletions

View File

@ -35,6 +35,7 @@ public enum AvatarNodeClipStyle {
case none case none
case round case round
case roundedRect case roundedRect
case bubble
} }
private class AvatarNodeParameters: NSObject { private class AvatarNodeParameters: NSObject {
@ -272,6 +273,25 @@ public final class AvatarEditOverlayNode: ASDisplayNode {
} }
public final class AvatarNode: ASDisplayNode { public final class AvatarNode: ASDisplayNode {
public static func avatarBubbleMask(size: CGSize) -> UIImage! {
return generateImage(size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor.white.cgColor)
AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: size))
context.fillPath()
})
}
public static func addAvatarBubblePath(context: CGContext, rect: CGRect) {
if let path = try? convertSvgPath("M60,30.274903 C60,46.843446 46.568544,60.274904 30,60.274904 C13.431458,60.274904 0,46.843446 0,30.274903 C0,23.634797 2.158635,17.499547 5.810547,12.529785 L6.036133,12.226074 C6.921364,10.896042 7.367402,8.104698 5.548828,5.316895 C3.606939,2.340088 1.186019,0.979668 2.399414,0.470215 C3.148032,0.156204 7.572027,0.000065 10.764648,1.790527 C12.148517,2.56662 13.2296,3.342422 14.09224,4.039734 C14.42622,4.309704 14.892063,4.349773 15.265962,4.138523 C19.618079,1.679604 24.644722,0.274902 30,0.274902 C46.568544,0.274902 60,13.70636 60,30.274903 Z ") {
var transform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 60.274904)
transform = CGAffineTransformScale(transform, rect.width / 60.0, rect.height / 60.0)
transform = CGAffineTransformTranslate(transform, rect.minX, rect.minY)
let transformedPath = path.copy(using: &transform)!
context.addPath(transformedPath)
}
}
public static let gradientColors: [[UIColor]] = [ public static let gradientColors: [[UIColor]] = [
[UIColor(rgb: 0xff516a), UIColor(rgb: 0xff885e)], [UIColor(rgb: 0xff516a), UIColor(rgb: 0xff885e)],
[UIColor(rgb: 0xffa85c), UIColor(rgb: 0xffcd6a)], [UIColor(rgb: 0xffa85c), UIColor(rgb: 0xffcd6a)],
@ -335,6 +355,7 @@ public final class AvatarNode: ASDisplayNode {
private var theme: PresentationTheme? private var theme: PresentationTheme?
private var overrideImage: AvatarNodeImageOverride? private var overrideImage: AvatarNodeImageOverride?
public let imageNode: ImageNode public let imageNode: ImageNode
private var imageNodeMask: UIImageView?
public var editOverlayNode: AvatarEditOverlayNode? public var editOverlayNode: AvatarEditOverlayNode?
private let imageReadyDisposable = MetaDisposable() private let imageReadyDisposable = MetaDisposable()
@ -399,7 +420,7 @@ public final class AvatarNode: ASDisplayNode {
self.displaysAsynchronously = true self.displaysAsynchronously = true
self.disableClearContentsOnHide = true self.disableClearContentsOnHide = true
self.imageNode.isLayerBacked = true self.imageNode.isUserInteractionEnabled = false
self.addSubnode(self.imageNode) self.addSubnode(self.imageNode)
self.imageNode.contentUpdated = { [weak self] image in self.imageNode.contentUpdated = { [weak self] image in
@ -434,6 +455,9 @@ public final class AvatarNode: ASDisplayNode {
public func updateSize(size: CGSize) { public func updateSize(size: CGSize) {
self.imageNode.frame = CGRect(origin: CGPoint(), size: size) self.imageNode.frame = CGRect(origin: CGPoint(), size: size)
self.editOverlayNode?.frame = self.imageNode.frame self.editOverlayNode?.frame = self.imageNode.frame
if let imageNodeMask = self.imageNodeMask {
imageNodeMask.frame = CGRect(origin: CGPoint(), size: size)
}
if !self.displaySuspended { if !self.displaySuspended {
self.setNeedsDisplay() self.setNeedsDisplay()
self.editOverlayNode?.setNeedsDisplay() self.editOverlayNode?.setNeedsDisplay()
@ -678,6 +702,7 @@ public final class AvatarNode: ASDisplayNode {
if self.params == params { if self.params == params {
return return
} }
let previousSize = self.params?.displayDimensions
self.params = params self.params = params
switch clipStyle { switch clipStyle {
@ -690,6 +715,29 @@ public final class AvatarNode: ASDisplayNode {
case .roundedRect: case .roundedRect:
self.imageNode.clipsToBounds = true self.imageNode.clipsToBounds = true
self.imageNode.cornerRadius = displayDimensions.height * 0.25 self.imageNode.cornerRadius = displayDimensions.height * 0.25
case .bubble:
break
}
if case .bubble = clipStyle {
var updateMask = false
let imageNodeMask: UIImageView
if let current = self.imageNodeMask {
imageNodeMask = current
updateMask = previousSize != params.displayDimensions
} else {
imageNodeMask = UIImageView()
self.imageNodeMask = imageNodeMask
self.imageNode.view.mask = imageNodeMask
imageNodeMask.frame = self.imageNode.frame
updateMask = true
}
if updateMask {
imageNodeMask.image = AvatarNode.avatarBubbleMask(size: params.displayDimensions)
}
} else if self.imageNodeMask != nil {
self.imageNodeMask = nil
self.imageNode.view.mask = nil
} }
if let imageCache = genericContext.imageCache as? DirectMediaImageCache, let peer, let smallProfileImage = peer.smallProfileImage, let peerReference = PeerReference(peer._asPeer()) { if let imageCache = genericContext.imageCache as? DirectMediaImageCache, let peer, let smallProfileImage = peer.smallProfileImage, let peerReference = PeerReference(peer._asPeer()) {
@ -1472,3 +1520,4 @@ public final class AvatarNode: ASDisplayNode {
} }
} }
} }

View File

@ -214,6 +214,9 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P
case .roundedRect: case .roundedRect:
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath)
context.clip() context.clip()
case .bubble:
AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset))
context.clip()
} }
var shouldBlur = false var shouldBlur = false
@ -265,6 +268,8 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P
} }
case .roundedRect: case .roundedRect:
break break
case .bubble:
break
} }
} else { } else {
if let emptyColor = emptyColor { if let emptyColor = emptyColor {
@ -279,6 +284,10 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P
context.beginPath() context.beginPath()
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath)
context.fillPath() context.fillPath()
case .bubble:
context.beginPath()
AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset))
context.clip()
} }
} }
} }
@ -295,6 +304,10 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P
context.beginPath() context.beginPath()
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath)
context.fillPath() context.fillPath()
case .bubble:
context.beginPath()
AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset))
context.clip()
} }
} }
@ -332,6 +345,10 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P
context.beginPath() context.beginPath()
context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath)
context.fillPath() context.fillPath()
case .bubble:
context.beginPath()
AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset))
context.clip()
} }
} }
}) })

View File

@ -1318,6 +1318,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
private var inlineNavigationMarkLayer: SimpleLayer? private var inlineNavigationMarkLayer: SimpleLayer?
public let titleNode: TextNode public let titleNode: TextNode
private var titleBadge: (backgroundView: UIImageView, textNode: TextNode)?
public let authorNode: AuthorNode public let authorNode: AuthorNode
private var compoundHighlightingNode: LinkHighlightingNode? private var compoundHighlightingNode: LinkHighlightingNode?
private var textArrowNode: ASImageNode? private var textArrowNode: ASImageNode?
@ -1835,10 +1836,19 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
self.avatarNode.font = avatarPlaceholderFont(size: avatarFontSize) self.avatarNode.font = avatarPlaceholderFont(size: avatarFontSize)
} }
} }
if peer.smallProfileImage != nil && overrideImage == nil { let avatarClipStyle: AvatarNodeClipStyle
self.avatarNode.setPeerV2(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: isForumAvatar ? .roundedRect : .round, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: avatarDiameter, height: avatarDiameter)) if peerIsMonoforum {
avatarClipStyle = .bubble
} else if isForumAvatar {
avatarClipStyle = .roundedRect
} else { } else {
self.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: isForumAvatar ? .roundedRect : .round, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: 60.0, height: 60.0)) avatarClipStyle = .round
}
if peer.smallProfileImage != nil && overrideImage == nil {
self.avatarNode.setPeerV2(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: avatarClipStyle, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: avatarDiameter, height: avatarDiameter))
} else {
self.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: avatarClipStyle, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: 60.0, height: 60.0))
} }
if peer.isPremium && peer.id != item.context.account.peerId { if peer.isPremium && peer.id != item.context.account.peerId {
@ -2028,6 +2038,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
let textLayout = TextNodeWithEntities.asyncLayout(self.textNode) let textLayout = TextNodeWithEntities.asyncLayout(self.textNode)
let makeTrailingTextBadgeLayout = TextNode.asyncLayout(self.trailingTextBadgeNode) let makeTrailingTextBadgeLayout = TextNode.asyncLayout(self.trailingTextBadgeNode)
let titleLayout = TextNode.asyncLayout(self.titleNode) let titleLayout = TextNode.asyncLayout(self.titleNode)
let titleBadgeLayout = TextNode.asyncLayout(self.titleBadge?.textNode)
let authorLayout = self.authorNode.asyncLayout() let authorLayout = self.authorNode.asyncLayout()
let makeMeasureLayout = TextNode.asyncLayout(self.measureNode) let makeMeasureLayout = TextNode.asyncLayout(self.measureNode)
let inputActivitiesLayout = self.inputActivitiesNode.asyncLayout() let inputActivitiesLayout = self.inputActivitiesNode.asyncLayout()
@ -2226,6 +2237,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
var textLeftCutout: CGFloat = 0.0 var textLeftCutout: CGFloat = 0.0
var dateAttributedString: NSAttributedString? var dateAttributedString: NSAttributedString?
var titleAttributedString: NSAttributedString? var titleAttributedString: NSAttributedString?
var titleBadgeText: String?
var badgeContent = ChatListBadgeContent.none var badgeContent = ChatListBadgeContent.none
var mentionBadgeContent = ChatListBadgeContent.none var mentionBadgeContent = ChatListBadgeContent.none
var statusState = ChatListStatusNodeState.none var statusState = ChatListStatusNodeState.none
@ -3001,12 +3013,11 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
} else { } else {
textColor = theme.titleColor textColor = theme.titleColor
} }
//TODO:localize
if case let .channel(channel) = itemPeer.peer, channel.flags.contains(.isMonoforum) { if case let .channel(channel) = itemPeer.peer, channel.flags.contains(.isMonoforum) {
titleAttributedString = NSAttributedString(string: "\(displayTitle) Messages", font: titleFont, textColor: textColor) //TODO:localize
} else { titleBadgeText = "MESSAGES"
titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor)
} }
titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor)
} }
case .group: case .group:
titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_ArchivedChatsTitle, font: titleFont, textColor: theme.titleColor) titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_ArchivedChatsTitle, font: titleFont, textColor: theme.titleColor)
@ -3224,7 +3235,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
default: default:
break break
} }
} else if case let .chat(itemPeer) = contentPeer, let peer = itemPeer.chatMainPeer { } else if case let .chat(itemPeer) = contentPeer, let peer = itemPeer.chatOrMonoforumMainPeer {
if peer.isSubscription { if peer.isSubscription {
isSubscription = true isSubscription = true
} }
@ -3369,7 +3380,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
} else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) { } else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) {
if forumThread != nil || !topForumTopicItems.isEmpty { if forumThread != nil || !topForumTopicItems.isEmpty {
if let forumThread { if let forumThread {
isFirstForumThreadSelectable = forumThread.isUnread isFirstForumThreadSelectable = false
forumThreads.append((id: forumThread.id, threadPeer: forumThread.threadPeer, title: NSAttributedString(string: forumThread.threadPeer?.compactDisplayTitle ?? " ", font: textFont, textColor: forumThread.isUnread || isSearching ? theme.authorNameColor : theme.messageTextColor), iconId: nil, iconColor: nil)) forumThreads.append((id: forumThread.id, threadPeer: forumThread.threadPeer, title: NSAttributedString(string: forumThread.threadPeer?.compactDisplayTitle ?? " ", font: textFont, textColor: forumThread.isUnread || isSearching ? theme.authorNameColor : theme.messageTextColor), iconId: nil, iconColor: nil))
} }
for topicItem in topForumTopicItems { for topicItem in topForumTopicItems {
@ -3463,11 +3474,19 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
titleAttributedString = NSAttributedString(string: " ", font: titleFont, textColor: theme.titleColor) titleAttributedString = NSAttributedString(string: " ", font: titleFont, textColor: theme.titleColor)
} }
let titleRectWidth = rawContentWidth - dateLayout.size.width - 10.0 - statusWidth - titleIconsWidth var titleRectWidth = rawContentWidth - dateLayout.size.width - 10.0 - statusWidth - titleIconsWidth
var titleCutout: TextNodeCutout? var titleCutout: TextNodeCutout?
if !titleLeftCutout.isZero { if !titleLeftCutout.isZero {
titleCutout = TextNodeCutout(topLeft: CGSize(width: titleLeftCutout, height: 10.0), topRight: nil, bottomRight: nil) titleCutout = TextNodeCutout(topLeft: CGSize(width: titleLeftCutout, height: 10.0), topRight: nil, bottomRight: nil)
} }
var titleBadgeLayoutAndApply: (TextNodeLayout, () -> TextNode)?
if let titleBadgeText {
let titleBadgeLayoutAndApplyValue = titleBadgeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleBadgeText, font: Font.semibold(11.0), textColor: theme.titleColor.withMultipliedAlpha(0.4)), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
titleBadgeLayoutAndApply = titleBadgeLayoutAndApplyValue
titleRectWidth = max(10.0, titleRectWidth - titleBadgeLayoutAndApplyValue.0.size.width - 8.0)
}
let (titleLayout, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: maxTitleLines, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: titleCutout, insets: UIEdgeInsets())) let (titleLayout, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: maxTitleLines, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: titleCutout, insets: UIEdgeInsets()))
var inputActivitiesSize: CGSize? var inputActivitiesSize: CGSize?
@ -4244,6 +4263,36 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
let contentDelta = CGPoint(x: contentRect.origin.x - (strongSelf.titleNode.frame.minX - titleOffset), y: contentRect.origin.y - (strongSelf.titleNode.frame.minY - UIScreenPixel)) let contentDelta = CGPoint(x: contentRect.origin.x - (strongSelf.titleNode.frame.minX - titleOffset), y: contentRect.origin.y - (strongSelf.titleNode.frame.minY - UIScreenPixel))
let titleFrame = CGRect(origin: CGPoint(x: contentRect.origin.x + titleOffset, y: contentRect.origin.y + UIScreenPixel), size: titleLayout.size) let titleFrame = CGRect(origin: CGPoint(x: contentRect.origin.x + titleOffset, y: contentRect.origin.y + UIScreenPixel), size: titleLayout.size)
strongSelf.titleNode.frame = titleFrame strongSelf.titleNode.frame = titleFrame
if let (titleBadgeLayout, titleBadgeApply) = titleBadgeLayoutAndApply {
let titleBadgeNode = titleBadgeApply()
let backgroundView: UIImageView
if let current = strongSelf.titleBadge {
backgroundView = current.backgroundView
} else {
backgroundView = UIImageView(image: generateStretchableFilledCircleImage(radius: 4.0, color: .white)?.withRenderingMode(.alwaysTemplate))
strongSelf.titleBadge = (backgroundView, titleBadgeNode)
strongSelf.mainContentContainerNode.view.addSubview(backgroundView)
strongSelf.mainContentContainerNode.addSubnode(titleBadgeNode)
}
let titleBadgeFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + titleIconsWidth + 10.0, y: titleFrame.minY + floor((titleFrame.height - titleBadgeLayout.size.height) * 0.5)), size: titleBadgeLayout.size)
titleBadgeNode.frame = titleBadgeFrame
var titleBadgeBackgroundFrame = titleBadgeFrame.insetBy(dx: -4.0, dy: -2.0)
titleBadgeBackgroundFrame.size.height -= 1.0
backgroundView.frame = titleBadgeBackgroundFrame
if item.presentationData.theme.overallDarkAppearance {
backgroundView.tintColor = theme.titleColor.withMultipliedAlpha(0.1)
} else {
backgroundView.tintColor = theme.titleColor.withMultipliedAlpha(0.05)
}
} else if let titleBadge = strongSelf.titleBadge {
strongSelf.titleBadge = nil
titleBadge.backgroundView.removeFromSuperview()
titleBadge.textNode.removeFromSupernode()
}
let authorNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height), size: authorLayout) let authorNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height), size: authorLayout)
strongSelf.authorNode.frame = authorNodeFrame strongSelf.authorNode.frame = authorNodeFrame
let textNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height - 1.0 + UIScreenPixel + (authorLayout.height.isZero ? 0.0 : (authorLayout.height - 3.0))), size: textLayout.size) let textNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height - 1.0 + UIScreenPixel + (authorLayout.height.isZero ? 0.0 : (authorLayout.height - 3.0))), size: textLayout.size)

View File

@ -430,6 +430,9 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch
if message.minAutoremoveOrClearTimeout == viewOnceTimeout { if message.minAutoremoveOrClearTimeout == viewOnceTimeout {
canReplyInAnotherChat = false canReplyInAnotherChat = false
} }
if let channel = message.peers[message.id.peerId] as? TelegramChannel, channel.isMonoForum {
canReplyInAnotherChat = false
}
} }
if canReplyInAnotherChat { if canReplyInAnotherChat {

View File

@ -548,7 +548,7 @@ extension ChatControllerImpl {
} else if let channel = peer as? TelegramChannel, channel.isMonoForum { } else if let channel = peer as? TelegramChannel, channel.isMonoForum {
if let linkedMonoforumId = channel.linkedMonoforumId, let mainPeer = peerView.peers[linkedMonoforumId] { if let linkedMonoforumId = channel.linkedMonoforumId, let mainPeer = peerView.peers[linkedMonoforumId] {
//TODO:localize //TODO:localize
strongSelf.state.chatTitleContent = .custom("\(mainPeer.debugDisplayTitle) Messages", nil, false) strongSelf.state.chatTitleContent = .custom(mainPeer.debugDisplayTitle, nil, false)
} else { } else {
strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, false) strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, false)
} }