mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Improve Dynamic Type in chat list
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user