diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 20df1d0353..15cf7c62b0 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -5431,15 +5431,15 @@ Any member of this group will be able to see messages in the channel."; "ChatListFolder.CategoryGroups" = "Groups"; "ChatListFolder.CategoryChannels" = "Channels"; "ChatListFolder.CategoryMuted" = "Muted"; -"ChatListFolder.CategoryRead" = "Muted"; +"ChatListFolder.CategoryRead" = "Read"; "ChatListFolder.CategoryArchived" = "Archived"; "ChatListFolder.NameSectionHeader" = "FOLDER NAME"; "ChatListFolder.NamePlaceholder" = "Folder Name"; "ChatListFolder.IncludedSectionHeader" = "INCLUDED CHATS"; "ChatListFolder.AddChats" = "Add Chats"; -"ChatListFolder.IncludeSectionInfo" = "Choose chats and types of chats that will appear in this filter."; +"ChatListFolder.IncludeSectionInfo" = "Choose chats and types of chats that will appear in this folder."; "ChatListFolder.ExcludedSectionHeader" = "EXCLUDED CHATS"; -"ChatListFolder.ExcludeSectionInfo" = "Choose chats and types of chats that will never appear in the filter."; +"ChatListFolder.ExcludeSectionInfo" = "Choose chats and types of chats that will never appear in the folder."; "ChatListFolder.NameNonMuted" = "Not Muted"; "ChatListFolder.NameUnread" = "Unread"; "ChatListFolder.NameChannels" = "Channels"; diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 019d7c04a7..75aca14017 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -2361,10 +2361,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, for preset in presetList { let filterType = chatListFilterType(preset) - var badge = "" + var badge: ContextMenuActionBadge? for item in filterItems { if item.0.id == preset.id && item.1 != 0 { - badge = "\(item.1)" + badge = ContextMenuActionBadge(value: "\(item.1)", color: item.2 ? .accent : .inactive) } } items.append(.action(ContextMenuActionItem(text: preset.title, badge: badge, icon: { theme in diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index c0d60df5b1..0e5658f5e9 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -274,7 +274,7 @@ private final class ChatListContainerItemNode: ASDisplayNode { private var floatingHeaderOffset: CGFloat? - private var emptyNode: ChatListEmptyNode? + private(set) var emptyNode: ChatListEmptyNode? var emptyShimmerEffectNode: ChatListShimmerNode? let listNode: ChatListNode @@ -583,6 +583,11 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate { case .began: self.transitionFractionOffset = 0.0 if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, isReorderingFilters, isEditing) = self.validLayout, let itemNode = self.itemNodes[self.selectedId] { + for (id, itemNode) in self.itemNodes { + if id != selectedId { + itemNode.emptyNode?.restartAnimation() + } + } if let presentationLayer = itemNode.layer.presentation() { self.transitionFraction = presentationLayer.frame.minX / layout.size.width self.transitionFractionOffset = self.transitionFraction diff --git a/submodules/ChatListUI/Sources/ChatListEmptyNode.swift b/submodules/ChatListUI/Sources/ChatListEmptyNode.swift index 63f0352da2..6cf16b4329 100644 --- a/submodules/ChatListUI/Sources/ChatListEmptyNode.swift +++ b/submodules/ChatListUI/Sources/ChatListEmptyNode.swift @@ -68,6 +68,10 @@ final class ChatListEmptyNode: ASDisplayNode { self.updateThemeAndStrings(theme: theme, strings: strings) } + func restartAnimation() { + self.animationNode.play() + } + func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { let string = NSMutableAttributedString(string: self.isFilter ? strings.ChatList_EmptyChatFilterList : strings.ChatList_EmptyChatList, font: Font.medium(17.0), textColor: theme.list.itemPrimaryTextColor) self.textNode.attributedText = string diff --git a/submodules/ContextUI/Sources/ContextActionNode.swift b/submodules/ContextUI/Sources/ContextActionNode.swift index 1b7af31951..a83ed1a60c 100644 --- a/submodules/ContextUI/Sources/ContextActionNode.swift +++ b/submodules/ContextUI/Sources/ContextActionNode.swift @@ -82,14 +82,26 @@ final class ContextActionNode: ASDisplayNode { } self.badgeBackgroundNode = ASImageNode() - self.badgeBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: presentationData.theme.contextMenu.badgeFillColor) self.badgeBackgroundNode.isAccessibilityElement = false self.badgeBackgroundNode.displaysAsynchronously = false self.badgeBackgroundNode.displayWithoutProcessing = true self.badgeBackgroundNode.isUserInteractionEnabled = false self.badgeTextNode = ImmediateTextNode() - self.badgeTextNode.attributedText = NSAttributedString(string: action.badge, font: Font.regular(14.0), textColor: presentationData.theme.contextMenu.badgeForegroundColor) + if let badge = action.badge { + let badgeFillColor: UIColor + let badgeForegroundColor: UIColor + switch badge.color { + case .accent: + badgeForegroundColor = presentationData.theme.contextMenu.badgeForegroundColor + badgeFillColor = presentationData.theme.contextMenu.badgeFillColor + case .inactive: + badgeForegroundColor = presentationData.theme.contextMenu.badgeInactiveForegroundColor + badgeFillColor = presentationData.theme.contextMenu.badgeInactiveFillColor + } + self.badgeBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: badgeFillColor) + self.badgeTextNode.attributedText = NSAttributedString(string: badge.value, font: Font.regular(14.0), textColor: badgeForegroundColor) + } self.badgeTextNode.isAccessibilityElement = false self.badgeTextNode.isUserInteractionEnabled = false self.badgeTextNode.displaysAsynchronously = false @@ -175,7 +187,7 @@ final class ContextActionNode: ASDisplayNode { if !statusSize.width.isZero, let statusNode = self.statusNode { let verticalSpacing: CGFloat = 2.0 let combinedTextHeight = textSize.height + verticalSpacing + statusSize.height - return (CGSize(width: max(textSize.width, statusSize.width) + sideInset + rightTextInset, height: verticalInset * 2.0 + combinedTextHeight), { size, transition in + return (CGSize(width: max(textSize.width, statusSize.width) + sideInset + rightTextInset + badgeWidthSpace, height: verticalInset * 2.0 + combinedTextHeight), { size, transition in let verticalOrigin = floor((size.height - combinedTextHeight) / 2.0) let textFrame = CGRect(origin: CGPoint(x: sideInset, y: verticalOrigin), size: textSize) transition.updateFrameAdditive(node: self.textNode, frame: textFrame) @@ -194,7 +206,7 @@ final class ContextActionNode: ASDisplayNode { transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))) }) } else { - return (CGSize(width: textSize.width + sideInset + rightTextInset, height: verticalInset * 2.0 + textSize.height), { size, transition in + return (CGSize(width: textSize.width + sideInset + rightTextInset + badgeWidthSpace, height: verticalInset * 2.0 + textSize.height), { size, transition in let verticalOrigin = floor((size.height - textSize.height) / 2.0) let textFrame = CGRect(origin: CGPoint(x: sideInset, y: verticalOrigin), size: textSize) transition.updateFrameAdditive(node: self.textNode, frame: textFrame) diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index bf3b21f1e1..f820cf0255 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -38,16 +38,31 @@ public struct ContextMenuActionItemIconSource { } } +public enum ContextMenuActionBadgeColor { + case accent + case inactive +} + +public struct ContextMenuActionBadge { + public var value: String + public var color: ContextMenuActionBadgeColor + + public init(value: String, color: ContextMenuActionBadgeColor) { + self.value = value + self.color = color + } +} + public final class ContextMenuActionItem { public let text: String public let textColor: ContextMenuActionItemTextColor public let textLayout: ContextMenuActionItemTextLayout - public let badge: String + public let badge: ContextMenuActionBadge? public let icon: (PresentationTheme) -> UIImage? public let iconSource: ContextMenuActionItemIconSource? public let action: (ContextController, @escaping (ContextMenuActionResult) -> Void) -> Void - public init(text: String, textColor: ContextMenuActionItemTextColor = .primary, textLayout: ContextMenuActionItemTextLayout = .twoLinesMax, badge: String = "", icon: @escaping (PresentationTheme) -> UIImage?, iconSource: ContextMenuActionItemIconSource? = nil, action: @escaping (ContextController, @escaping (ContextMenuActionResult) -> Void) -> Void) { + public init(text: String, textColor: ContextMenuActionItemTextColor = .primary, textLayout: ContextMenuActionItemTextLayout = .twoLinesMax, badge: ContextMenuActionBadge? = nil, icon: @escaping (PresentationTheme) -> UIImage?, iconSource: ContextMenuActionItemIconSource? = nil, action: @escaping (ContextController, @escaping (ContextMenuActionResult) -> Void) -> Void) { self.text = text self.textColor = textColor self.textLayout = textLayout diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index 3f7ddcd5bb..896fa3bb4f 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -861,7 +861,7 @@ private final class SettingsControllerImpl: ItemListController, SettingsControll for account in other { let id = account.0.id - items.append(.action(ContextMenuActionItem(text: account.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? "\(account.2)" : "", icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: accountIconSignal(account: account.0, peer: account.1, size: avatarSize)), action: { [weak self] _, f in + items.append(.action(ContextMenuActionItem(text: account.1.displayTitle(strings: strings, displayOrder: presentationData.nameDisplayOrder), badge: account.2 != 0 ? ContextMenuActionBadge(value: "\(account.2)", color: .accent) : nil, icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: accountIconSignal(account: account.0, peer: account.1, size: avatarSize)), action: { [weak self] _, f in guard let strongSelf = self else { return } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index 1c46f2cefc..f915ef5080 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -523,8 +523,10 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati primaryColor: UIColor(rgb: 0xffffff, alpha: 1.0), secondaryColor: UIColor(rgb: 0xffffff, alpha: 0.8), destructiveColor: UIColor(rgb: 0xeb5545), - badgeFillColor: UIColor(rgb: 0xeb5545), - badgeForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0), + badgeFillColor: UIColor(rgb: 0xffffff), + badgeForegroundColor: UIColor(rgb: 0x000000), + badgeInactiveFillColor: UIColor(rgb: 0xffffff).withAlphaComponent(0.5), + badgeInactiveForegroundColor: UIColor(rgb: 0x000000), extractedContentTintColor: UIColor(rgb: 0xffffff, alpha: 1.0) ) diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 47cc9108cf..97773ee663 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -772,8 +772,10 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres primaryColor: UIColor(rgb: 0xffffff, alpha: 1.0), secondaryColor: UIColor(rgb: 0xffffff, alpha: 0.8), destructiveColor: UIColor(rgb: 0xff6767), - badgeFillColor: UIColor(rgb: 0xff6767), - badgeForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0), + badgeFillColor: accentColor, + badgeForegroundColor: secondaryBadgeTextColor, + badgeInactiveFillColor: mainSecondaryTextColor.withAlphaComponent(0.4), + badgeInactiveForegroundColor: secondaryBadgeTextColor, extractedContentTintColor: UIColor(rgb: 0xffffff, alpha: 1.0) ) diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 20fbe6f575..db69b58cd5 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -734,8 +734,10 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio primaryColor: UIColor(rgb: 0x000000, alpha: 1.0), secondaryColor: UIColor(rgb: 0x000000, alpha: 0.8), destructiveColor: UIColor(rgb: 0xff3b30), - badgeFillColor: UIColor(rgb: 0xff3b30), + badgeFillColor: UIColor(rgb: 0x007ee5), badgeForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0), + badgeInactiveFillColor: UIColor(rgb: 0xb6b6bb), + badgeInactiveForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0), extractedContentTintColor: .white ) diff --git a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift index f6e2d4d650..5ea950e487 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift @@ -269,9 +269,11 @@ public final class PresentationThemeContextMenu { public let destructiveColor: UIColor public let badgeFillColor: UIColor public let badgeForegroundColor: UIColor + public let badgeInactiveFillColor: UIColor + public let badgeInactiveForegroundColor: UIColor public let extractedContentTintColor: UIColor - init(dimColor: UIColor, backgroundColor: UIColor, itemSeparatorColor: UIColor, sectionSeparatorColor: UIColor, itemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, primaryColor: UIColor, secondaryColor: UIColor, destructiveColor: UIColor, badgeFillColor: UIColor, badgeForegroundColor: UIColor, extractedContentTintColor: UIColor) { + init(dimColor: UIColor, backgroundColor: UIColor, itemSeparatorColor: UIColor, sectionSeparatorColor: UIColor, itemBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, primaryColor: UIColor, secondaryColor: UIColor, destructiveColor: UIColor, badgeFillColor: UIColor, badgeForegroundColor: UIColor, badgeInactiveFillColor: UIColor, badgeInactiveForegroundColor: UIColor, extractedContentTintColor: UIColor) { self.dimColor = dimColor self.backgroundColor = backgroundColor self.itemSeparatorColor = itemSeparatorColor @@ -283,11 +285,13 @@ public final class PresentationThemeContextMenu { self.destructiveColor = destructiveColor self.badgeFillColor = badgeFillColor self.badgeForegroundColor = badgeForegroundColor + self.badgeInactiveFillColor = badgeInactiveFillColor + self.badgeInactiveForegroundColor = badgeInactiveForegroundColor self.extractedContentTintColor = extractedContentTintColor } public func withUpdated(dimColor: UIColor? = nil, backgroundColor: UIColor? = nil, itemSeparatorColor: UIColor? = nil, sectionSeparatorColor: UIColor? = nil, itemBackgroundColor: UIColor? = nil, itemHighlightedBackgroundColor: UIColor? = nil, primaryColor: UIColor? = nil, secondaryColor: UIColor? = nil, destructiveColor: UIColor? = nil) -> PresentationThemeContextMenu { - return PresentationThemeContextMenu(dimColor: dimColor ?? self.dimColor, backgroundColor: backgroundColor ?? self.backgroundColor, itemSeparatorColor: itemSeparatorColor ?? self.itemSeparatorColor, sectionSeparatorColor: sectionSeparatorColor ?? self.sectionSeparatorColor, itemBackgroundColor: itemBackgroundColor ?? self.itemBackgroundColor, itemHighlightedBackgroundColor: itemHighlightedBackgroundColor ?? self.itemHighlightedBackgroundColor, primaryColor: primaryColor ?? self.primaryColor, secondaryColor: secondaryColor ?? self.secondaryColor, destructiveColor: destructiveColor ?? self.destructiveColor, badgeFillColor: self.badgeFillColor, badgeForegroundColor: self.badgeForegroundColor, extractedContentTintColor: self.extractedContentTintColor) + return PresentationThemeContextMenu(dimColor: dimColor ?? self.dimColor, backgroundColor: backgroundColor ?? self.backgroundColor, itemSeparatorColor: itemSeparatorColor ?? self.itemSeparatorColor, sectionSeparatorColor: sectionSeparatorColor ?? self.sectionSeparatorColor, itemBackgroundColor: itemBackgroundColor ?? self.itemBackgroundColor, itemHighlightedBackgroundColor: itemHighlightedBackgroundColor ?? self.itemHighlightedBackgroundColor, primaryColor: primaryColor ?? self.primaryColor, secondaryColor: secondaryColor ?? self.secondaryColor, destructiveColor: destructiveColor ?? self.destructiveColor, badgeFillColor: self.badgeFillColor, badgeForegroundColor: self.badgeForegroundColor, badgeInactiveFillColor: self.badgeInactiveFillColor, badgeInactiveForegroundColor: self.badgeInactiveForegroundColor, extractedContentTintColor: self.extractedContentTintColor) } } diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift index 165d9c5e2e..678f980236 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift @@ -1637,6 +1637,8 @@ extension PresentationThemeContextMenu: Codable { case destructive case badgeFill case badgeForeground + case badgeInactiveFill + case badgeInactiveForeground case extractedTint } @@ -1656,6 +1658,8 @@ extension PresentationThemeContextMenu: Codable { destructiveColor: destructiveColor, badgeFillColor: (try? decodeColor(values, .badgeFill)) ?? destructiveColor, badgeForegroundColor: (try? decodeColor(values, .badgeForeground)) ?? backgroundColor, + badgeInactiveFillColor: (try? decodeColor(values, .badgeInactiveFill)) ?? destructiveColor, + badgeInactiveForegroundColor: (try? decodeColor(values, .badgeInactiveForeground)) ?? backgroundColor, extractedContentTintColor: (try? decodeColor(values, .extractedTint)) ?? backgroundColor ) }