diff --git a/submodules/ChatListUI/Sources/Node/ChatListBadgeNode.swift b/submodules/ChatListUI/Sources/Node/ChatListBadgeNode.swift index 92d837b2d9..8e1ff49f1f 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListBadgeNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListBadgeNode.swift @@ -33,8 +33,6 @@ private func measureString(_ string: String) -> String { } } -private let badgeFont = Font.regular(14.0) - final class ChatListBadgeNode: ASDisplayNode { private let backgroundNode: ASImageNode private let textNode: TextNode @@ -63,13 +61,13 @@ final class ChatListBadgeNode: ASDisplayNode { self.addSubnode(self.textNode) } - func asyncLayout() -> (CGSize, UIImage?, ChatListBadgeContent) -> (CGSize, (Bool, Bool) -> Void) { + func asyncLayout() -> (CGSize, CGFloat, UIFont, UIImage?, ChatListBadgeContent) -> (CGSize, (Bool, Bool) -> Void) { let textLayout = TextNode.asyncLayout(self.textNode) let measureTextLayout = TextNode.asyncLayout(self.measureTextNode) let currentContent = self.content - return { [weak self] boundingSize, backgroundImage, content in + return { [weak self] boundingSize, imageWidth, badgeFont, backgroundImage, content in var badgeWidth: CGFloat = 0.0 var textLayoutAndApply: (TextNodeLayout, () -> TextNode)? @@ -79,14 +77,14 @@ final class ChatListBadgeNode: ASDisplayNode { let (measureLayout, _) = measureTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: measureString(text.string), font: badgeFont, textColor: .black), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: boundingSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - badgeWidth = max(20.0, measureLayout.size.width + 10.0) + badgeWidth = max(imageWidth, measureLayout.size.width + imageWidth / 2.0) case .mention, .blank: - badgeWidth = 20.0 + badgeWidth = imageWidth case .none: badgeWidth = 0.0 } - return (CGSize(width: badgeWidth, height: 20.0), { animated, bounce in + return (CGSize(width: badgeWidth, height: imageWidth), { animated, bounce in if let strongSelf = self { strongSelf.content = content @@ -98,7 +96,7 @@ final class ChatListBadgeNode: ASDisplayNode { return } - let badgeWidth = max(20.0, badgeWidth) + let badgeWidth = max(imageWidth, badgeWidth) let previousBadgeWidth = !strongSelf.backgroundNode.frame.width.isZero ? strongSelf.backgroundNode.frame.width : badgeWidth var animateTextNode = false diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 38226faa3b..04323a0a4c 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -654,7 +654,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let titleFont = Font.medium(floor(item.presentationData.fontSize.itemListBaseFontSize * 16.0 / 17.0)) let textFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 15.0 / 17.0)) let dateFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 14.0 / 17.0)) - let badgeFont = Font.regular(14.0) + let badgeFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 14.0 / 17.0)) let account = item.context.account var message: Message? @@ -777,9 +777,11 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let enableChatListPhotos = item.context.sharedContext.immediateExperimentalUISettings.chatListPhotos - let avatarDiameter = floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0) + let avatarDiameter = min(60.0, floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0)) let avatarLeftInset = 18.0 + avatarDiameter + let badgeDiameter = floor(item.presentationData.fontSize.baseDisplaySize * 20.0 / 17.0) + let leftInset: CGFloat = params.leftInset + avatarLeftInset enum ContentData { @@ -995,10 +997,10 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { } else { let badgeTextColor: UIColor if unreadCount.muted { - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme, diameter: badgeDiameter) badgeTextColor = theme.unreadBadgeInactiveTextColor } else { - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.presentationData.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.presentationData.theme, diameter: badgeDiameter) badgeTextColor = theme.unreadBadgeActiveTextColor } let unreadCountText = compactNumericCountString(Int(unreadCount.count), decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator) @@ -1012,7 +1014,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if let mutedCount = unreadCount.mutedCount, mutedCount > 0 { let mutedUnreadCountText = compactNumericCountString(Int(mutedCount), decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator) - currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme) + currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme, diameter: badgeDiameter) mentionBadgeContent = .text(NSAttributedString(string: mutedUnreadCountText, font: badgeFont, textColor: theme.unreadBadgeInactiveTextColor)) } } @@ -1024,13 +1026,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if !isPeerGroup { if totalMentionCount > 0 { if Namespaces.PeerGroup.archive == item.peerGroupId { - currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundInactiveMention(item.presentationData.theme) + currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundInactiveMention(item.presentationData.theme, diameter: badgeDiameter) } else { - currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundMention(item.presentationData.theme) + currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundMention(item.presentationData.theme, diameter: badgeDiameter) } mentionBadgeContent = .mention } else if item.index.pinningIndex != nil && !isAd && currentBadgeBackgroundImage == nil { - currentPinnedIconImage = PresentationResourcesChatList.badgeBackgroundPinned(item.presentationData.theme) + currentPinnedIconImage = PresentationResourcesChatList.badgeBackgroundPinned(item.presentationData.theme, diameter: badgeDiameter) } } @@ -1105,9 +1107,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { let (dateLayout, dateApply) = dateLayout(TextNodeLayoutArguments(attributedString: dateAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (badgeLayout, badgeApply) = badgeLayout(CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), currentBadgeBackgroundImage, badgeContent) + let (badgeLayout, badgeApply) = badgeLayout(CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), badgeDiameter, badgeFont, currentBadgeBackgroundImage, badgeContent) - let (mentionBadgeLayout, mentionBadgeApply) = mentionBadgeLayout(CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), currentMentionBadgeImage, mentionBadgeContent) + let (mentionBadgeLayout, mentionBadgeApply) = mentionBadgeLayout(CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), badgeDiameter, badgeFont, currentMentionBadgeImage, mentionBadgeContent) var badgeSize: CGFloat = 0.0 if !badgeLayout.width.isZero { @@ -1656,7 +1658,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { transition.updateFrame(node: reorderControlNode, frame: reorderControlFrame) } - let avatarDiameter = floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0) + let avatarDiameter = min(60.0, floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0)) let avatarLeftInset = 18.0 + avatarDiameter let leftInset: CGFloat = params.leftInset + avatarLeftInset diff --git a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift index f0eba4a8ab..7e9ef44c72 100644 --- a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift +++ b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift @@ -591,10 +591,10 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode { let badgeTextColor: UIColor switch badge.type { case .inactive: - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.presentationData.theme, diameter: 20.0) badgeTextColor = item.presentationData.theme.chatList.unreadBadgeInactiveTextColor case .active: - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.presentationData.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.presentationData.theme, diameter: 20.0) badgeTextColor = item.presentationData.theme.chatList.unreadBadgeActiveTextColor } let badgeAttributedString = NSAttributedString(string: badge.count > 0 ? "\(badge.count)" : " ", font: badgeFont, textColor: badgeTextColor) diff --git a/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift b/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift index fee77ef7d4..bbff42ee43 100644 --- a/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift +++ b/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift @@ -148,10 +148,10 @@ public final class HorizontalPeerItemNode: ListViewItemNode { let badgeTextColor: UIColor let (unreadCount, isMuted) = unreadBadge if isMuted { - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundInactive(item.theme, diameter: 20.0) badgeTextColor = item.theme.chatList.unreadBadgeInactiveTextColor } else { - currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.theme) + currentBadgeBackgroundImage = PresentationResourcesChatList.badgeBackgroundActive(item.theme, diameter: 20.0) badgeTextColor = item.theme.chatList.unreadBadgeActiveTextColor } badgeAttributedString = NSAttributedString(string: unreadCount > 0 ? "\(unreadCount)" : " ", font: badgeFont, textColor: badgeTextColor) diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 12fdc82903..a1b0744fad 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -228,4 +228,10 @@ public enum PresentationResourceParameterKey: Hashable { case chatMediaPartialCheck(CGFloat) case chatFreeFullCheck(CGFloat, Bool) case chatFreePartialCheck(CGFloat, Bool) + + case chatListBadgeBackgroundActive(CGFloat) + case chatListBadgeBackgroundInactive(CGFloat) + case chatListBadgeBackgroundMention(CGFloat) + case chatListBadgeBackgroundInactiveMention(CGFloat) + case chatListBadgeBackgroundPinned(CGFloat) } diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift index 77dd16f219..12aca8462b 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift @@ -19,8 +19,8 @@ private func generateStatusCheckImage(theme: PresentationTheme, single: Bool) -> }) } -private func generateBadgeBackgroundImage(theme: PresentationTheme, active: Bool, icon: UIImage? = nil) -> UIImage? { - return generateImage(CGSize(width: 20.0, height: 20.0), contextGenerator: { size, context in +private func generateBadgeBackgroundImage(theme: PresentationTheme, diameter: CGFloat, active: Bool, icon: UIImage? = nil) -> UIImage? { + return generateImage(CGSize(width: diameter, height: diameter), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) if active { context.setFillColor(theme.chatList.unreadBadgeActiveBackgroundColor.cgColor) @@ -31,7 +31,7 @@ private func generateBadgeBackgroundImage(theme: PresentationTheme, active: Bool if let icon = icon, let cgImage = icon.cgImage { context.draw(cgImage, in: CGRect(origin: CGPoint(x: floor((size.width - icon.size.width) / 2.0), y: floor((size.height - icon.size.height) / 2.0)), size: icon.size)) } - })?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 10) + })?.stretchableImage(withLeftCapWidth: Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) } private func generateClockFrameImage(color: UIColor) -> UIImage? { @@ -169,32 +169,32 @@ public struct PresentationResourcesChatList { }) } - public static func badgeBackgroundActive(_ theme: PresentationTheme) -> UIImage? { - return theme.image(PresentationResourceKey.chatListBadgeBackgroundActive.rawValue, { theme in - return generateBadgeBackgroundImage(theme: theme, active: true) + public static func badgeBackgroundActive(_ theme: PresentationTheme, diameter: CGFloat) -> UIImage? { + return theme.image(PresentationResourceParameterKey.chatListBadgeBackgroundActive(diameter), { theme in + return generateBadgeBackgroundImage(theme: theme, diameter: diameter, active: true) }) } - public static func badgeBackgroundInactive(_ theme: PresentationTheme) -> UIImage? { - return theme.image(PresentationResourceKey.chatListBadgeBackgroundInactive.rawValue, { theme in - return generateBadgeBackgroundImage(theme: theme, active: false) + public static func badgeBackgroundInactive(_ theme: PresentationTheme, diameter: CGFloat) -> UIImage? { + return theme.image(PresentationResourceParameterKey.chatListBadgeBackgroundInactive(diameter), { theme in + return generateBadgeBackgroundImage(theme: theme, diameter: diameter, active: false) }) } - public static func badgeBackgroundMention(_ theme: PresentationTheme) -> UIImage? { - return theme.image(PresentationResourceKey.chatListBadgeBackgroundMention.rawValue, { theme in - return generateBadgeBackgroundImage(theme: theme, active: true, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeActiveTextColor)) + public static func badgeBackgroundMention(_ theme: PresentationTheme, diameter: CGFloat) -> UIImage? { + return theme.image(PresentationResourceParameterKey.chatListBadgeBackgroundMention(diameter), { theme in + return generateBadgeBackgroundImage(theme: theme, diameter: diameter, active: true, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeActiveTextColor)) }) } - public static func badgeBackgroundInactiveMention(_ theme: PresentationTheme) -> UIImage? { - return theme.image(PresentationResourceKey.chatListBadgeBackgroundInactiveMention.rawValue, { theme in - return generateBadgeBackgroundImage(theme: theme, active: false, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeInactiveTextColor)) + public static func badgeBackgroundInactiveMention(_ theme: PresentationTheme, diameter: CGFloat) -> UIImage? { + return theme.image(PresentationResourceParameterKey.chatListBadgeBackgroundInactiveMention(diameter), { theme in + return generateBadgeBackgroundImage(theme: theme, diameter: diameter, active: false, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeInactiveTextColor)) }) } - public static func badgeBackgroundPinned(_ theme: PresentationTheme) -> UIImage? { - return theme.image(PresentationResourceKey.chatListBadgeBackgroundPinned.rawValue, { theme in + public static func badgeBackgroundPinned(_ theme: PresentationTheme, diameter: CGFloat) -> UIImage? { + return theme.image(PresentationResourceParameterKey.chatListBadgeBackgroundPinned(diameter), { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/PeerPinnedIcon"), color: theme.chatList.pinnedBadgeColor) }) } diff --git a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift index f4734e7a13..33a435c828 100644 --- a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift @@ -175,7 +175,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { self.presentationInterfaceState = interfaceState if previousState?.theme !== interfaceState.theme { - self.badgeBackground.image = PresentationResourcesChatList.badgeBackgroundActive(interfaceState.theme) + self.badgeBackground.image = PresentationResourcesChatList.badgeBackgroundActive(interfaceState.theme, diameter: 20.0) } if previousState?.peerDiscussionId != interfaceState.peerDiscussionId {