diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index d82188f008..a61a4d9ec1 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -592,6 +592,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { backgroundColor: .clear, separatorColor: strongSelf.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5), hideTopPanel: hideTopPanel, + disableTopPanel: strongSelf.alwaysAllowPremiumReactions, hideTopPanelUpdated: { hideTopPanel, transition in guard let strongSelf = self else { return @@ -1217,6 +1218,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { backgroundColor: .clear, separatorColor: self.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5), hideTopPanel: hideTopPanel, + disableTopPanel: self.alwaysAllowPremiumReactions, hideTopPanelUpdated: { [weak self] hideTopPanel, transition in guard let strongSelf = self else { return diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift index bb3d266454..b932696754 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift @@ -1496,32 +1496,61 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString switch updatedValue { case .all: - rawText = self.presentationData.strings.Channel_AdminLog_ReactionsEnabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") - case let .limited(reactions): - let emojiString = reactions.compactMap({ reaction -> String? in - switch reaction { - case let .builtin(value): - return value - case .custom: - return nil + let rawText = self.presentationData.strings.Channel_AdminLog_ReactionsEnabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") + appendAttributedText(text: rawText, generateEntities: { index in + if index == 0, let author = author { + return [.TextMention(peerId: author.id)] + } else if index == 1 { + return [.Bold] } - }).joined(separator: ", ") - rawText = self.presentationData.strings.Channel_AdminLog_AllowedReactionsUpdated(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", emojiString) - case .empty: - rawText = self.presentationData.strings.Channel_AdminLog_ReactionsDisabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") - } - - appendAttributedText(text: rawText, generateEntities: { index in - if index == 0, let author = author { - return [.TextMention(peerId: author.id)] - } else if index == 1 { - return [.Bold] + return [] + }, to: &text, entities: &entities) + case let .limited(reactions): + let authorTitle = author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "" + let rawText = self.presentationData.strings.Channel_AdminLog_AllowedReactionsUpdated(authorTitle, "") + var previousIndex = 0 + let nsText = rawText.string as NSString + for range in rawText.ranges.sorted(by: { $0.range.lowerBound < $1.range.lowerBound }) { + if range.range.lowerBound > previousIndex { + text.append(nsText.substring(with: NSRange(location: previousIndex, length: range.range.lowerBound - previousIndex))) + } + if range.index == 0 { + if let author { + entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (authorTitle as NSString).length, type: .TextMention(peerId: author.id))) + } + text.append(authorTitle) + } else if range.index == 1 { + for reaction in reactions { + let reactionText: String + switch reaction { + case let .builtin(value): + reactionText = value + text.append(reactionText) + case let .custom(fileId): + reactionText = "." + entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (reactionText as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: fileId))) + text.append(reactionText) + } + } + } + previousIndex = range.range.upperBound } - return [] - }, to: &text, entities: &entities) + if nsText.length > previousIndex { + text.append(nsText.substring(with: NSRange(location: previousIndex, length: nsText.length - previousIndex))) + } + case .empty: + let rawText = self.presentationData.strings.Channel_AdminLog_ReactionsDisabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") + appendAttributedText(text: rawText, generateEntities: { index in + if index == 0, let author = author { + return [.TextMention(peerId: author.id)] + } else if index == 1 { + return [.Bold] + } + return [] + }, to: &text, entities: &entities) + } let action = TelegramMediaActionType.customText(text: text, entities: entities) diff --git a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift index 347d40036f..8df436290e 100644 --- a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift @@ -65,6 +65,7 @@ public final class EmojiStatusSelectionComponent: Component { public let backgroundColor: UIColor public let separatorColor: UIColor public let hideTopPanel: Bool + public let disableTopPanel: Bool public let hideTopPanelUpdated: (Bool, Transition) -> Void public init( @@ -75,6 +76,7 @@ public final class EmojiStatusSelectionComponent: Component { backgroundColor: UIColor, separatorColor: UIColor, hideTopPanel: Bool, + disableTopPanel: Bool, hideTopPanelUpdated: @escaping (Bool, Transition) -> Void ) { self.theme = theme @@ -84,6 +86,7 @@ public final class EmojiStatusSelectionComponent: Component { self.backgroundColor = backgroundColor self.separatorColor = separatorColor self.hideTopPanel = hideTopPanel + self.disableTopPanel = disableTopPanel self.hideTopPanelUpdated = hideTopPanelUpdated } @@ -109,6 +112,9 @@ public final class EmojiStatusSelectionComponent: Component { if lhs.hideTopPanel != rhs.hideTopPanel { return false } + if lhs.disableTopPanel != rhs.disableTopPanel { + return false + } return true } @@ -193,7 +199,8 @@ public final class EmojiStatusSelectionComponent: Component { displayBottomPanel: false, isExpanded: false, clipContentToTopPanel: false, - useExternalSearchContainer: false + useExternalSearchContainer: false, + hidePanels: component.disableTopPanel )), environment: {}, containerSize: availableSize @@ -984,6 +991,7 @@ public final class EmojiStatusSelectionController: ViewController { backgroundColor: listBackgroundColor, separatorColor: separatorColor, hideTopPanel: self.isReactionSearchActive, + disableTopPanel: false, hideTopPanelUpdated: { [weak self] hideTopPanel, transition in guard let strongSelf = self else { return