From 56a4beb1747d3e36a931f6669e2271b6923fcf81 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 28 Oct 2020 22:31:45 +0400 Subject: [PATCH] Filter bio entities --- .../Sources/CreatePollController.swift | 2 +- .../Sources/ChannelInfoController.swift | 2 +- .../Sources/GroupInfoController.swift | 2 +- .../Sources/UserInfoController.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 4 ++-- .../ChatMessageWebpageBubbleContentNode.swift | 2 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 15 ++++++------ .../Sources/GenerateTextEntities.swift | 24 +++++++++++++++---- 8 files changed, 35 insertions(+), 18 deletions(-) diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index 8771c27e46..befd7498d2 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -811,7 +811,7 @@ public func createPollController(context: AccountContext, peer: Peer, isQuiz: Bo if state.isQuiz { kind = .quiz if !state.solutionText.value.string.isEmpty { - let entities = generateTextEntities(state.solutionText.value.string, enabledTypes: .url, currentEntities: generateChatInputTextEntities(state.solutionText.value)) + let entities = generateTextEntities(state.solutionText.value.string, enabledTypes: .allUrl, currentEntities: generateChatInputTextEntities(state.solutionText.value)) resolvedSolution = TelegramMediaPollResults.Solution(text: state.solutionText.value.string, entities: entities) } } else { diff --git a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift index 3efed590b4..47c265fe01 100644 --- a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift @@ -334,7 +334,7 @@ private enum ChannelInfoEntry: ItemListNodeEntry { arguments.tapAvatarAction() }, context: arguments.avatarAndNameInfoContext, updatingImage: updatingAvatar) case let .about(theme, text, value): - return ItemListTextWithLabelItem(presentationData: presentationData, label: text, text: foldMultipleLineBreaks(value), enabledEntityTypes: [.url, .mention, .hashtag], multiline: true, sectionId: self.section, action: nil, longTapAction: { + return ItemListTextWithLabelItem(presentationData: presentationData, label: text, text: foldMultipleLineBreaks(value), enabledEntityTypes: [.allUrl, .mention, .hashtag], multiline: true, sectionId: self.section, action: nil, longTapAction: { arguments.displayContextMenu(ChannelInfoEntryTag.about, value) }, linkItemAction: { action, itemLink in arguments.aboutLinkAction(action, itemLink) diff --git a/submodules/PeerInfoUI/Sources/GroupInfoController.swift b/submodules/PeerInfoUI/Sources/GroupInfoController.swift index 585ba2ecaa..72f2de42d4 100644 --- a/submodules/PeerInfoUI/Sources/GroupInfoController.swift +++ b/submodules/PeerInfoUI/Sources/GroupInfoController.swift @@ -507,7 +507,7 @@ private enum GroupInfoEntry: ItemListNodeEntry { arguments.changeProfilePhoto() }) case let .about(theme, text): - return ItemListMultilineTextItem(presentationData: presentationData, text: foldMultipleLineBreaks(text), enabledEntityTypes: [.url, .mention, .hashtag], sectionId: self.section, style: .blocks, longTapAction: { + return ItemListMultilineTextItem(presentationData: presentationData, text: foldMultipleLineBreaks(text), enabledEntityTypes: [.allUrl, .mention, .hashtag], sectionId: self.section, style: .blocks, longTapAction: { arguments.displayAboutContextMenu(text) }, linkItemAction: { action, itemLink in arguments.aboutLinkAction(action, itemLink) diff --git a/submodules/PeerInfoUI/Sources/UserInfoController.swift b/submodules/PeerInfoUI/Sources/UserInfoController.swift index 5cf6a75cbc..98fc345ac9 100644 --- a/submodules/PeerInfoUI/Sources/UserInfoController.swift +++ b/submodules/PeerInfoUI/Sources/UserInfoController.swift @@ -410,7 +410,7 @@ private enum UserInfoEntry: ItemListNodeEntry { case let .about(theme, peer, text, value): var enabledEntityTypes: EnabledEntityTypes = [] if let peer = peer as? TelegramUser, let _ = peer.botInfo { - enabledEntityTypes = [.url, .mention, .hashtag] + enabledEntityTypes = [.allUrl, .mention, .hashtag] } return ItemListTextWithLabelItem(presentationData: presentationData, label: text, text: foldMultipleLineBreaks(value), enabledEntityTypes: enabledEntityTypes, multiline: true, sectionId: self.section, action: nil, longTapAction: { arguments.displayAboutContextMenu(value) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index ded50af1a3..8ba77a354d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -8146,7 +8146,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G public func displayPromoAnnouncement(text: String) { let psaText: String = text - let psaEntities: [MessageTextEntity] = generateTextEntities(psaText, enabledTypes: .url) + let psaEntities: [MessageTextEntity] = generateTextEntities(psaText, enabledTypes: .allUrl) var found = false self.forEachController({ controller in @@ -8239,7 +8239,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G psaText = string } - let psaEntities: [MessageTextEntity] = generateTextEntities(psaText, enabledTypes: .url) + let psaEntities: [MessageTextEntity] = generateTextEntities(psaText, enabledTypes: .allUrl) let messageId = item.message.id diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index e8068b2e85..dccfe0125d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -122,7 +122,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { if let textValue = webpage.text, !textValue.isEmpty { text = textValue - var entityTypes: EnabledEntityTypes = [.url] + var entityTypes: EnabledEntityTypes = [.allUrl] switch type { case .twitter, .instagram: entityTypes.insert(.mention) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index ab94f05d5f..a536be47e3 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -621,7 +621,8 @@ private final class PeerInfoInteraction { } } -private let enabledBioEntities: EnabledEntityTypes = [.url, .mention, .hashtag] +private let enabledPublicBioEntities: EnabledEntityTypes = [.allUrl, .mention, .hashtag] +private let enabledPrivateBioEntities: EnabledEntityTypes = [.internalUrl, .mention, .hashtag] private enum SettingsSection: Int, CaseIterable { case edit @@ -927,11 +928,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese } if let cachedData = data.cachedData as? CachedUserData { if user.isScam { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo, text: user.botInfo != nil ? presentationData.strings.UserInfo_ScamBotWarning : presentationData.strings.UserInfo_ScamUserWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.botInfo != nil ? enabledBioEntities : []), action: nil, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo, text: user.botInfo != nil ? presentationData.strings.UserInfo_ScamBotWarning : presentationData.strings.UserInfo_ScamUserWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.botInfo != nil ? enabledPrivateBioEntities : []), action: nil, requestLayout: { interaction.requestLayout() })) } else if let about = cachedData.about, !about.isEmpty { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledPrivateBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { interaction.requestLayout() })) } @@ -1015,11 +1016,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese } if let cachedData = data.cachedData as? CachedChannelData { if channel.isScam { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: ItemAbout, label: presentationData.strings.Channel_AboutItem, text: presentationData.strings.GroupInfo_ScamGroupWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledBioEntities), action: nil, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: ItemAbout, label: presentationData.strings.Channel_AboutItem, text: presentationData.strings.GroupInfo_ScamGroupWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledPublicBioEntities), action: nil, requestLayout: { interaction.requestLayout() })) } else if let about = cachedData.about, !about.isEmpty { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: ItemAbout, label: presentationData.strings.Channel_AboutItem, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: ItemAbout, label: presentationData.strings.Channel_AboutItem, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledPublicBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { interaction.requestLayout() })) } @@ -1051,11 +1052,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese } else if let group = data.peer as? TelegramGroup { if let cachedData = data.cachedData as? CachedGroupData { if group.isScam { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_GroupAboutItem, text: presentationData.strings.GroupInfo_ScamGroupWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledBioEntities), action: nil, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_GroupAboutItem, text: presentationData.strings.GroupInfo_ScamGroupWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledPublicBioEntities), action: nil, requestLayout: { interaction.requestLayout() })) } else if let about = cachedData.about, !about.isEmpty { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_GroupAboutItem, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { + items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_GroupAboutItem, text: about, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: enabledPublicBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: { interaction.requestLayout() })) } diff --git a/submodules/TextFormat/Sources/GenerateTextEntities.swift b/submodules/TextFormat/Sources/GenerateTextEntities.swift index 6fa025aa5d..8121c86b23 100644 --- a/submodules/TextFormat/Sources/GenerateTextEntities.swift +++ b/submodules/TextFormat/Sources/GenerateTextEntities.swift @@ -85,12 +85,13 @@ public struct EnabledEntityTypes: OptionSet { public static let command = EnabledEntityTypes(rawValue: 1 << 0) public static let mention = EnabledEntityTypes(rawValue: 1 << 1) public static let hashtag = EnabledEntityTypes(rawValue: 1 << 2) - public static let url = EnabledEntityTypes(rawValue: 1 << 3) + public static let allUrl = EnabledEntityTypes(rawValue: 1 << 3) public static let phoneNumber = EnabledEntityTypes(rawValue: 1 << 4) public static let timecode = EnabledEntityTypes(rawValue: 1 << 5) public static let external = EnabledEntityTypes(rawValue: 1 << 6) + public static let internalUrl = EnabledEntityTypes(rawValue: 1 << 7) - public static let all: EnabledEntityTypes = [.command, .mention, .hashtag, .url, .phoneNumber] + public static let all: EnabledEntityTypes = [.command, .mention, .hashtag, .allUrl, .phoneNumber] } private func commitEntity(_ utf16: String.UTF16View, _ type: CurrentEntityType, _ range: Range, _ enabledTypes: EnabledEntityTypes, _ entities: inout [MessageTextEntity], mediaDuration: Double? = nil) { @@ -160,11 +161,11 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType let utf16 = text.utf16 var detector: NSDataDetector? - if enabledTypes.contains(.phoneNumber) && enabledTypes.contains(.url) { + if enabledTypes.contains(.phoneNumber) && (enabledTypes.contains(.allUrl) || enabledTypes.contains(.internalUrl)) { detector = dataAndPhoneNumberDetector } else if enabledTypes.contains(.phoneNumber) { detector = phoneNumberDetector - } else if enabledTypes.contains(.url) { + } else if enabledTypes.contains(.allUrl) || enabledTypes.contains(.internalUrl) { detector = dataDetector } @@ -179,6 +180,21 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType if let lowerBound = lowerBound, let upperBound = upperBound { let type: MessageTextEntityType if result.resultType == NSTextCheckingResult.CheckingType.link { + if !enabledTypes.contains(.allUrl) && enabledTypes.contains(.internalUrl) { + guard let url = result.url else { + return + } + if url.scheme != "tg" { + guard let host = url.host?.lowercased() else { + return + } + if host == "telegram.org" || host == "t.me" { + } else { + return + } + } + } + type = .Url } else { type = .PhoneNumber