From 37c605a981d2d3a2ecbd8a604b34fa68d3ee6c27 Mon Sep 17 00:00:00 2001 From: levochkaa Date: Sun, 4 May 2025 22:59:01 +0400 Subject: [PATCH 1/4] (open)Id/Dc/CreationDate/RegDate(ContextMenu) --- .../Sources/PeerInfoScreen.swift | 173 +++++++++++++----- 1 file changed, 127 insertions(+), 46 deletions(-) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 7c88e04bdb..cba8feaa49 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -498,7 +498,6 @@ private enum PeerInfoMemberAction { private enum PeerInfoContextSubject { case copy(String) - case aboutDC case bio case phone(String) case link(customLink: String?) @@ -624,6 +623,10 @@ private final class PeerInfoInteraction { let openWorkingHoursContextMenu: (ASDisplayNode, ContextGesture?) -> Void let openBusinessLocationContextMenu: (ASDisplayNode, ContextGesture?) -> Void let openBirthdayContextMenu: (ASDisplayNode, ContextGesture?) -> Void + let openIdContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void + let openDcContextMenu: (ASDisplayNode, ContextGesture?) -> Void + let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void + let openRegDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void let editingOpenAffiliateProgram: () -> Void let editingOpenVerifyAccounts: () -> Void let editingToggleAutoTranslate: (Bool) -> Void @@ -698,6 +701,10 @@ private final class PeerInfoInteraction { openWorkingHoursContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, openBusinessLocationContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, openBirthdayContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, + openIdContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, + openDcContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, + openCreationDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, + openRegDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, editingOpenAffiliateProgram: @escaping () -> Void, editingOpenVerifyAccounts: @escaping () -> Void, editingToggleAutoTranslate: @escaping (Bool) -> Void, @@ -771,6 +778,10 @@ private final class PeerInfoInteraction { self.openWorkingHoursContextMenu = openWorkingHoursContextMenu self.openBusinessLocationContextMenu = openBusinessLocationContextMenu self.openBirthdayContextMenu = openBirthdayContextMenu + self.openIdContextMenu = openIdContextMenu + self.openDcContextMenu = openDcContextMenu + self.openCreationDateContextMenu = openCreationDateContextMenu + self.openRegDateContextMenu = openRegDateContextMenu self.editingOpenAffiliateProgram = editingOpenAffiliateProgram self.editingOpenVerifyAccounts = editingOpenVerifyAccounts self.editingToggleAutoTranslate = editingToggleAutoTranslate @@ -1357,6 +1368,18 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: let birthdayContextAction: (ASDisplayNode, ContextGesture?, CGPoint?) -> Void = { node, gesture, _ in interaction.openBirthdayContextMenu(node, gesture) } + let openIdContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, id in + interaction.openIdContextMenu(node, gesture, id) + } + let openDcContextMenu: (ASDisplayNode, ContextGesture?) -> Void = { node, gesture in + interaction.openDcContextMenu(node, gesture) + } + let openRegDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, regDate in + interaction.openRegDateContextMenu(node, gesture, regDate) + } + let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, creationDate in + interaction.openCreationDateContextMenu(node, gesture, creationDate) + } if let user = data.peer as? TelegramUser { // MARK: Swiftgram @@ -2105,11 +2128,11 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: // MARK: Swiftgram if showProfileId { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, label: "id: \(idText)", text: "", textColor: .primary, action: nil, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.copy(idText), sourceNode, nil) - }, requestLayout: { _ in - interaction.requestLayout(false) - })) + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "id", text: idText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + openIdContextMenu(node, nil, idText) + }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in + openIdContextMenu(node, gesture, idText) + }, requestLayout: { _ in })) sgItemId += 1 } @@ -2119,7 +2142,7 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: var phoneCountryText = "" var dcLabel = "" - var dcText: String = "" +// var dcText: String = "" if let cachedData = data.cachedData as? CachedUserData, let phoneCountry = cachedData.peerStatusSettings?.phoneCountry { var countryName = "" @@ -2153,25 +2176,25 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: } if let dcId = dcId { - dcLabel = "dc: \(dcId)" - if phoneCountryText.isEmpty { + dcLabel = "\(dcId)" +// if phoneCountryText.isEmpty { // if !dcLocation.isEmpty { // dcLabel += " \(dcLocation)" // } - } else { - dcText = "\(phoneCountryText)" - } +// } else { +// dcText = "\(phoneCountryText)" +// } } else if !phoneCountryText.isEmpty { - dcLabel = "dc: ?" - dcText = phoneCountryText + dcLabel = "?" +// dcText = phoneCountryText } - if !dcText.isEmpty || !dcLabel.isEmpty { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, label: dcLabel, text: dcText, textColor: .primary, action: nil, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.aboutDC, sourceNode, nil) - }, requestLayout: { _ in - interaction.requestLayout(false) - })) + if !dcLabel.isEmpty { + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "dc", text: dcLabel, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + openDcContextMenu(node, nil) + }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in + openDcContextMenu(node, gesture) + }, requestLayout: { _ in })) sgItemId += 1 } } @@ -2179,11 +2202,11 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if SGSimpleSettings.shared.showCreationDate { if let channelCreationTimestamp = data.channelCreationTimestamp { let creationDateString = stringForDate(timestamp: channelCreationTimestamp, strings: presentationData.strings) - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, label: i18n("Chat.Created", presentationData.strings.baseLanguageCode, creationDateString), text: "", action: nil, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.copy(creationDateString), sourceNode, nil) - }, requestLayout: { _ in - interaction.requestLayout(false) - })) + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "Chat.Created", text: creationDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + openCreationDateContextMenu(node, nil, creationDateString) + }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in + openCreationDateContextMenu(node, gesture, creationDateString) + }, requestLayout: { _ in })) sgItemId += 1 } } @@ -2220,11 +2243,11 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: } } if !regDateString.isEmpty { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, label: i18n("Chat.RegDate", presentationData.strings.baseLanguageCode), text: regDateString, action: nil, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.copy(regDateString), sourceNode, nil) - }, requestLayout: { _ in - interaction.requestLayout(false) - })) + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "Chat.RegDate", text: regDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + openRegDateContextMenu(node, nil, regDateString) + }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in + openRegDateContextMenu(node, gesture, regDateString) + }, requestLayout: { _ in })) sgItemId += 1 } } @@ -3457,6 +3480,18 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } self.openBirthdayContextMenu(node: node, gesture: gesture) + }, openIdContextMenu: { [weak self] node, gesture, id in + guard let self else { return } + self.openIdContextMenu(node: node, gesture: gesture, id: id) + }, openDcContextMenu: { [weak self] node, gesture in + guard let self else { return } + self.openDcContextMenu(node: node, gesture: gesture) + }, openCreationDateContextMenu: { [weak self] node, gesture, creationDate in + guard let self else { return } + self.openCreationDateContextMenu(node: node, gesture: gesture, creationDate: creationDate) + }, openRegDateContextMenu: { [weak self] node, gesture, regDate in + guard let self else { return } + self.openRegDateContextMenu(node: node, gesture: gesture, regDate: regDate) }, editingOpenAffiliateProgram: { [weak self] in guard let self else { return @@ -8232,6 +8267,68 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.controller?.present(contextController, in: .window(.root)) } + private func openIdContextMenu(node: ASDisplayNode, gesture: ContextGesture?, id: String) { + guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } + let copyAction = { [weak self] in + guard let self else { return } + UIPasteboard.general.string = id + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied ID"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + } + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: "Copy ID", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss { copyAction() } + }))) + let actions = ContextController.Items(content: .list(items)) + let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) + self.controller?.present(contextController, in: .window(.root)) + } + + private func openDcContextMenu(node: ASDisplayNode, gesture: ContextGesture?) { + guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } + let learnMoreAction = { [weak self] in + self?.openUrl(url: "https://core.telegram.org/api/datacenter", concealed: false, external: false) + } + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Passport_InfoLearnMore, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Browser"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss { learnMoreAction() } + }))) + let actions = ContextController.Items(content: .list(items)) + let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) + self.controller?.present(contextController, in: .window(.root)) + } + + private func openCreationDateContextMenu(node: ASDisplayNode, gesture: ContextGesture?, creationDate: String) { + guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } + let copyAction = { [weak self] in + guard let self else { return } + UIPasteboard.general.string = creationDate + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied creation date"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + } + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: "Copy Creation Date", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss { copyAction() } + }))) + let actions = ContextController.Items(content: .list(items)) + let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) + self.controller?.present(contextController, in: .window(.root)) + } + + private func openRegDateContextMenu(node: ASDisplayNode, gesture: ContextGesture?, regDate: String) { + guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } + let copyAction = { [weak self] in + guard let self else { return } + UIPasteboard.general.string = regDate + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied registration date"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + } + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: "Copy Registration Date", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss { copyAction() } + }))) + let actions = ContextController.Items(content: .list(items)) + let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) + self.controller?.present(contextController, in: .window(.root)) + } + private func openPhone(value: String, node: ASDisplayNode, gesture: ContextGesture?, progress: Promise?) { guard let sourceNode = node as? ContextExtractedContentContainingNode else { return @@ -9835,22 +9932,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return nil } })) - case .aboutDC: - let contextMenuController = makeContextMenuController(actions: [ContextMenuAction(content: .text(title: self.presentationData.strings.Passport_InfoLearnMore, accessibilityLabel: self.presentationData.strings.Passport_InfoLearnMore), action: { [weak self] in - self?.openUrl(url: "https://core.telegram.org/api/datacenter", concealed: false, external: false) - - })]) - controller.present(contextMenuController, in: .window(.root), with: ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak self, weak sourceNode] in - if let controller = self?.controller, let sourceNode = sourceNode { - var rect = sourceNode.bounds.insetBy(dx: 0.0, dy: 2.0) - if let sourceRect = sourceRect { - rect = sourceRect.insetBy(dx: 0.0, dy: 2.0) - } - return (sourceNode, rect, controller.displayNode, controller.view.bounds) - } else { - return nil - } - })) case .bio: var text: String? From 3cbb7f3a2578dd8cd6a4972b68f002f86c779c83 Mon Sep 17 00:00:00 2001 From: levochkaa Date: Mon, 12 May 2025 00:25:18 +0400 Subject: [PATCH 2/4] bring back dcText --- .../Sources/PeerInfoScreen.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index cba8feaa49..3092171c34 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -2142,7 +2142,7 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: var phoneCountryText = "" var dcLabel = "" -// var dcText: String = "" + var dcText: String = "" if let cachedData = data.cachedData as? CachedUserData, let phoneCountry = cachedData.peerStatusSettings?.phoneCountry { var countryName = "" @@ -2176,21 +2176,21 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: } if let dcId = dcId { - dcLabel = "\(dcId)" -// if phoneCountryText.isEmpty { + dcLabel = "dc: \(dcId)" + if phoneCountryText.isEmpty { // if !dcLocation.isEmpty { // dcLabel += " \(dcLocation)" // } -// } else { -// dcText = "\(phoneCountryText)" -// } + } else { + dcText = "\(phoneCountryText)" + } } else if !phoneCountryText.isEmpty { - dcLabel = "?" -// dcText = phoneCountryText + dcLabel = "dc: ?" + dcText = phoneCountryText } if !dcLabel.isEmpty { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "dc", text: dcLabel, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: dcLabel, text: dcText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in openDcContextMenu(node, nil) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in openDcContextMenu(node, gesture) From 9468ad8b59dd5b50fe845740f2def304482731b4 Mon Sep 17 00:00:00 2001 From: levochkaa Date: Mon, 12 May 2025 01:10:40 +0400 Subject: [PATCH 3/4] translations & joined date --- .../Strings/en.lproj/SGLocalizable.strings | 14 +++-- .../Sources/PeerInfoScreen.swift | 53 ++++++++++++++----- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/Swiftgram/SGStrings/Strings/en.lproj/SGLocalizable.strings b/Swiftgram/SGStrings/Strings/en.lproj/SGLocalizable.strings index f37c56ea3f..99e9528f87 100644 --- a/Swiftgram/SGStrings/Strings/en.lproj/SGLocalizable.strings +++ b/Swiftgram/SGStrings/Strings/en.lproj/SGLocalizable.strings @@ -121,13 +121,21 @@ "Settings.DefaultEmojisFirst" = "Standard emojis first"; "Settings.DefaultEmojisFirst.Notice" = "Show standard emojis before premium in emoji keyboard"; -/* Date when chat was created. "created: 24 May 2016" */ -"Chat.Created" = "created: %@"; - +"Chat.Created" = "Created"; +"Chat.Created.Copy" = "Copy Creation Date"; +"Chat.Created.Copied" = "Creation Date copied to clipboard."; /* Date when user joined the chat. "Joined Swiftgram Chat" */ "Chat.JoinedDateTitle" = "Joined %@"; +"Chat.JoinedDate.Copy" = "Copy Joined Date"; +"Chat.JoinedDate.Copied" = "Joined Date copied to clipboard."; /* Date when user registered in Telegram. Will be shown like "Registered\n24 May 2016" */ "Chat.RegDate" = "Registered"; +"Chat.RegDate.Copy" = "Copy Registration Date"; +"Chat.RegDate.Copied" = "Registration Date copied to clipboard."; + +"Chat.ID" = "id"; +"Chat.ID.Copy" = "Copy ID"; +"Chat.ID.Copied" = "ID copied to clipboard."; "Settings.messageDoubleTapActionOutgoingEdit" = "Double-tap to edit message"; diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 3092171c34..40555f6d39 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -626,6 +626,7 @@ private final class PeerInfoInteraction { let openIdContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void let openDcContextMenu: (ASDisplayNode, ContextGesture?) -> Void let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void + let openJoinedContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void let openRegDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void let editingOpenAffiliateProgram: () -> Void let editingOpenVerifyAccounts: () -> Void @@ -704,6 +705,7 @@ private final class PeerInfoInteraction { openIdContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, openDcContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, openCreationDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, + openJoinedContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, openRegDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, editingOpenAffiliateProgram: @escaping () -> Void, editingOpenVerifyAccounts: @escaping () -> Void, @@ -781,6 +783,7 @@ private final class PeerInfoInteraction { self.openIdContextMenu = openIdContextMenu self.openDcContextMenu = openDcContextMenu self.openCreationDateContextMenu = openCreationDateContextMenu + self.openJoinedContextMenu = openJoinedContextMenu self.openRegDateContextMenu = openRegDateContextMenu self.editingOpenAffiliateProgram = editingOpenAffiliateProgram self.editingOpenVerifyAccounts = editingOpenVerifyAccounts @@ -1380,6 +1383,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, creationDate in interaction.openCreationDateContextMenu(node, gesture, creationDate) } + let openJoinedContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, joinedDate in + interaction.openJoinedContextMenu(node, gesture, joinedDate) + } if let user = data.peer as? TelegramUser { // MARK: Swiftgram @@ -2128,7 +2134,7 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: // MARK: Swiftgram if showProfileId { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "id", text: idText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.ID", presentationData.strings.baseLanguageCode), text: idText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in openIdContextMenu(node, nil, idText) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in openIdContextMenu(node, gesture, idText) @@ -2202,7 +2208,7 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if SGSimpleSettings.shared.showCreationDate { if let channelCreationTimestamp = data.channelCreationTimestamp { let creationDateString = stringForDate(timestamp: channelCreationTimestamp, strings: presentationData.strings) - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "Chat.Created", text: creationDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.Created", presentationData.strings.baseLanguageCode), text: creationDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in openCreationDateContextMenu(node, nil, creationDateString) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in openCreationDateContextMenu(node, gesture, creationDateString) @@ -2213,11 +2219,11 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if let invitedAt = nearestChatParticipant.1 { let joinedDateString = stringForDate(timestamp: invitedAt, strings: presentationData.strings) - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, label: i18n("Chat.JoinedDateTitle", presentationData.strings.baseLanguageCode, nearestChatParticipant.0 ?? "chat") , text: joinedDateString, action: nil, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.copy(joinedDateString), sourceNode, nil) - }, requestLayout: { _ in - interaction.requestLayout(false) - })) + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.JoinedDateTitle", presentationData.strings.baseLanguageCode, nearestChatParticipant.0 ?? "chat"), text: joinedDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + openJoinedContextMenu(node, nil, joinedDateString) + }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in + openJoinedContextMenu(node, gesture, joinedDateString) + }, requestLayout: { _ in })) sgItemId += 1 } @@ -2243,7 +2249,7 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: } } if !regDateString.isEmpty { - items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: "Chat.RegDate", text: regDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in + items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.RegDate", presentationData.strings.baseLanguageCode), text: regDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in openRegDateContextMenu(node, nil, regDateString) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in openRegDateContextMenu(node, gesture, regDateString) @@ -3489,6 +3495,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, openCreationDateContextMenu: { [weak self] node, gesture, creationDate in guard let self else { return } self.openCreationDateContextMenu(node: node, gesture: gesture, creationDate: creationDate) + }, openJoinedContextMenu: { [weak self] node, gesture, joinedDate in + guard let self else { return } + self.openJoinedContextMenu(node: node, gesture: gesture, joinedDate: joinedDate) }, openRegDateContextMenu: { [weak self] node, gesture, regDate in guard let self else { return } self.openRegDateContextMenu(node: node, gesture: gesture, regDate: regDate) @@ -8272,10 +8281,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let copyAction = { [weak self] in guard let self else { return } UIPasteboard.general.string = id - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied ID"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.ID.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: "Copy ID", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + items.append(.action(ContextMenuActionItem(text: i18n("Chat.ID.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c?.dismiss { copyAction() } }))) let actions = ContextController.Items(content: .list(items)) @@ -8302,10 +8311,26 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let copyAction = { [weak self] in guard let self else { return } UIPasteboard.general.string = creationDate - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied creation date"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.Created.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: "Copy Creation Date", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + items.append(.action(ContextMenuActionItem(text: i18n("Chat.Created.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss { copyAction() } + }))) + let actions = ContextController.Items(content: .list(items)) + let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) + self.controller?.present(contextController, in: .window(.root)) + } + + private func openJoinedContextMenu(node: ASDisplayNode, gesture: ContextGesture?, joinedDate: String) { + guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } + let copyAction = { [weak self] in + guard let self else { return } + UIPasteboard.general.string = joinedDate + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.JoinedDate.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + } + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: i18n("Chat.JoinedDate.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c?.dismiss { copyAction() } }))) let actions = ContextController.Items(content: .list(items)) @@ -8318,10 +8343,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let copyAction = { [weak self] in guard let self else { return } UIPasteboard.general.string = regDate - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Copied registration date"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.RegDate.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: "Copy Registration Date", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + items.append(.action(ContextMenuActionItem(text: i18n("Chat.RegDate.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c?.dismiss { copyAction() } }))) let actions = ContextController.Items(content: .list(items)) From db5f55cfa5f15296273a0b86e6902cf0f9ff7b59 Mon Sep 17 00:00:00 2001 From: levochkaa Date: Mon, 12 May 2025 01:30:55 +0400 Subject: [PATCH 4/4] shared method --- .../Sources/PeerInfoScreen.swift | 155 +++++------------- 1 file changed, 43 insertions(+), 112 deletions(-) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 40555f6d39..4ed9501b34 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -555,6 +555,11 @@ private enum TopicsLimitedReason { case discussion } +private enum SGContextMenuAction { + case copy(text: String, copyKey: String, copiedKey: String) + case openURL(url: String) +} + private final class PeerInfoInteraction { let notifyTextCopied: () -> Void let openChat: (EnginePeer.Id?) -> Void @@ -623,11 +628,7 @@ private final class PeerInfoInteraction { let openWorkingHoursContextMenu: (ASDisplayNode, ContextGesture?) -> Void let openBusinessLocationContextMenu: (ASDisplayNode, ContextGesture?) -> Void let openBirthdayContextMenu: (ASDisplayNode, ContextGesture?) -> Void - let openIdContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void - let openDcContextMenu: (ASDisplayNode, ContextGesture?) -> Void - let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void - let openJoinedContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void - let openRegDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void + let openSgContextMenu: (ASDisplayNode, ContextGesture?, SGContextMenuAction) -> Void let editingOpenAffiliateProgram: () -> Void let editingOpenVerifyAccounts: () -> Void let editingToggleAutoTranslate: (Bool) -> Void @@ -702,11 +703,7 @@ private final class PeerInfoInteraction { openWorkingHoursContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, openBusinessLocationContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, openBirthdayContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, - openIdContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, - openDcContextMenu: @escaping (ASDisplayNode, ContextGesture?) -> Void, - openCreationDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, - openJoinedContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, - openRegDateContextMenu: @escaping (ASDisplayNode, ContextGesture?, String) -> Void, + openSgContextMenu: @escaping (ASDisplayNode, ContextGesture?, SGContextMenuAction) -> Void, editingOpenAffiliateProgram: @escaping () -> Void, editingOpenVerifyAccounts: @escaping () -> Void, editingToggleAutoTranslate: @escaping (Bool) -> Void, @@ -780,11 +777,7 @@ private final class PeerInfoInteraction { self.openWorkingHoursContextMenu = openWorkingHoursContextMenu self.openBusinessLocationContextMenu = openBusinessLocationContextMenu self.openBirthdayContextMenu = openBirthdayContextMenu - self.openIdContextMenu = openIdContextMenu - self.openDcContextMenu = openDcContextMenu - self.openCreationDateContextMenu = openCreationDateContextMenu - self.openJoinedContextMenu = openJoinedContextMenu - self.openRegDateContextMenu = openRegDateContextMenu + self.openSgContextMenu = openSgContextMenu self.editingOpenAffiliateProgram = editingOpenAffiliateProgram self.editingOpenVerifyAccounts = editingOpenVerifyAccounts self.editingToggleAutoTranslate = editingToggleAutoTranslate @@ -1371,20 +1364,8 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: let birthdayContextAction: (ASDisplayNode, ContextGesture?, CGPoint?) -> Void = { node, gesture, _ in interaction.openBirthdayContextMenu(node, gesture) } - let openIdContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, id in - interaction.openIdContextMenu(node, gesture, id) - } - let openDcContextMenu: (ASDisplayNode, ContextGesture?) -> Void = { node, gesture in - interaction.openDcContextMenu(node, gesture) - } - let openRegDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, regDate in - interaction.openRegDateContextMenu(node, gesture, regDate) - } - let openCreationDateContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, creationDate in - interaction.openCreationDateContextMenu(node, gesture, creationDate) - } - let openJoinedContextMenu: (ASDisplayNode, ContextGesture?, String) -> Void = { node, gesture, joinedDate in - interaction.openJoinedContextMenu(node, gesture, joinedDate) + let openSgContextMenu: (ASDisplayNode, ContextGesture?, SGContextMenuAction) -> Void = { node, gesture, action in + interaction.openSgContextMenu(node, gesture, action) } if let user = data.peer as? TelegramUser { @@ -2135,9 +2116,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: // MARK: Swiftgram if showProfileId { items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.ID", presentationData.strings.baseLanguageCode), text: idText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in - openIdContextMenu(node, nil, idText) + openSgContextMenu(node, nil, .copy(text: idText, copyKey: "Chat.ID.Copy", copiedKey: "Chat.ID.Copied")) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in - openIdContextMenu(node, gesture, idText) + openSgContextMenu(node, gesture, .copy(text: idText, copyKey: "Chat.ID.Copy", copiedKey: "Chat.ID.Copied")) }, requestLayout: { _ in })) sgItemId += 1 } @@ -2197,9 +2178,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if !dcLabel.isEmpty { items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: dcLabel, text: dcText, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in - openDcContextMenu(node, nil) + openSgContextMenu(node, nil, .openURL(url: "https://core.telegram.org/api/datacenter")) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in - openDcContextMenu(node, gesture) + openSgContextMenu(node, gesture, .openURL(url: "https://core.telegram.org/api/datacenter")) }, requestLayout: { _ in })) sgItemId += 1 } @@ -2209,9 +2190,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if let channelCreationTimestamp = data.channelCreationTimestamp { let creationDateString = stringForDate(timestamp: channelCreationTimestamp, strings: presentationData.strings) items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.Created", presentationData.strings.baseLanguageCode), text: creationDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in - openCreationDateContextMenu(node, nil, creationDateString) + openSgContextMenu(node, nil, .copy(text: creationDateString, copyKey: "Chat.Created.Copy", copiedKey: "Chat.Created.Copied")) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in - openCreationDateContextMenu(node, gesture, creationDateString) + openSgContextMenu(node, nil, .copy(text: creationDateString, copyKey: "Chat.Created.Copy", copiedKey: "Chat.Created.Copied")) }, requestLayout: { _ in })) sgItemId += 1 } @@ -2220,9 +2201,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: if let invitedAt = nearestChatParticipant.1 { let joinedDateString = stringForDate(timestamp: invitedAt, strings: presentationData.strings) items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.JoinedDateTitle", presentationData.strings.baseLanguageCode, nearestChatParticipant.0 ?? "chat"), text: joinedDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in - openJoinedContextMenu(node, nil, joinedDateString) + openSgContextMenu(node, nil, .copy(text: joinedDateString, copyKey: "Chat.JoinedDate.Copy", copiedKey: "Chat.JoinedDate.Copied")) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in - openJoinedContextMenu(node, gesture, joinedDateString) + openSgContextMenu(node, nil, .copy(text: joinedDateString, copyKey: "Chat.JoinedDate.Copy", copiedKey: "Chat.JoinedDate.Copied")) }, requestLayout: { _ in })) sgItemId += 1 } @@ -2250,9 +2231,9 @@ private func infoItems(nearestChatParticipant: (String?, Int32?), showProfileId: } if !regDateString.isEmpty { items[.swiftgram]!.append(PeerInfoScreenLabeledValueItem(id: sgItemId, context: context, label: i18n("Chat.RegDate", presentationData.strings.baseLanguageCode), text: regDateString, textColor: .primary, leftIcon: nil, icon: nil, action: { node, _ in - openRegDateContextMenu(node, nil, regDateString) + openSgContextMenu(node, nil, .copy(text: regDateString, copyKey: "Chat.RegDate.Copy", copiedKey: "Chat.RegDate.Copied")) }, longTapAction: nil, iconAction: nil, contextAction: { node, gesture, _ in - openRegDateContextMenu(node, gesture, regDateString) + openSgContextMenu(node, nil, .copy(text: regDateString, copyKey: "Chat.RegDate.Copy", copiedKey: "Chat.RegDate.Copied")) }, requestLayout: { _ in })) sgItemId += 1 } @@ -3486,22 +3467,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro return } self.openBirthdayContextMenu(node: node, gesture: gesture) - }, openIdContextMenu: { [weak self] node, gesture, id in - guard let self else { return } - self.openIdContextMenu(node: node, gesture: gesture, id: id) - }, openDcContextMenu: { [weak self] node, gesture in - guard let self else { return } - self.openDcContextMenu(node: node, gesture: gesture) - }, openCreationDateContextMenu: { [weak self] node, gesture, creationDate in - guard let self else { return } - self.openCreationDateContextMenu(node: node, gesture: gesture, creationDate: creationDate) - }, openJoinedContextMenu: { [weak self] node, gesture, joinedDate in - guard let self else { return } - self.openJoinedContextMenu(node: node, gesture: gesture, joinedDate: joinedDate) - }, openRegDateContextMenu: { [weak self] node, gesture, regDate in - guard let self else { return } - self.openRegDateContextMenu(node: node, gesture: gesture, regDate: regDate) - }, editingOpenAffiliateProgram: { [weak self] in + }, openSgContextMenu: { [weak self] node, gesture, action in + guard let self else { + return + } + self.openSgContextMenu(node: node, gesture: gesture, action: action) + }, editingOpenAffiliateProgram: { [weak self] in guard let self else { return } @@ -8276,17 +8247,25 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.controller?.present(contextController, in: .window(.root)) } - private func openIdContextMenu(node: ASDisplayNode, gesture: ContextGesture?, id: String) { + private func openSgContextMenu(node: ASDisplayNode, gesture: ContextGesture?, action: SGContextMenuAction) { guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } - let copyAction = { [weak self] in - guard let self else { return } - UIPasteboard.general.string = id - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.ID.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) - } var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: i18n("Chat.ID.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in - c?.dismiss { copyAction() } - }))) + switch action { + case let .copy(text, copyKey, copiedKey): + items.append(.action(ContextMenuActionItem(text: i18n(copyKey, self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in + c?.dismiss { [weak self] in + guard let self else { return } + UIPasteboard.general.string = text + self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n(copiedKey, self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + } + }))) + case let .openURL(url): + items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Passport_InfoLearnMore, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Browser"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in + c?.dismiss { [weak self] in + self?.openUrl(url: url, concealed: false, external: false) + } + }))) + } let actions = ContextController.Items(content: .list(items)) let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) self.controller?.present(contextController, in: .window(.root)) @@ -8306,54 +8285,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.controller?.present(contextController, in: .window(.root)) } - private func openCreationDateContextMenu(node: ASDisplayNode, gesture: ContextGesture?, creationDate: String) { - guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } - let copyAction = { [weak self] in - guard let self else { return } - UIPasteboard.general.string = creationDate - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.Created.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) - } - var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: i18n("Chat.Created.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in - c?.dismiss { copyAction() } - }))) - let actions = ContextController.Items(content: .list(items)) - let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) - self.controller?.present(contextController, in: .window(.root)) - } - - private func openJoinedContextMenu(node: ASDisplayNode, gesture: ContextGesture?, joinedDate: String) { - guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } - let copyAction = { [weak self] in - guard let self else { return } - UIPasteboard.general.string = joinedDate - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.JoinedDate.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) - } - var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: i18n("Chat.JoinedDate.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in - c?.dismiss { copyAction() } - }))) - let actions = ContextController.Items(content: .list(items)) - let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) - self.controller?.present(contextController, in: .window(.root)) - } - - private func openRegDateContextMenu(node: ASDisplayNode, gesture: ContextGesture?, regDate: String) { - guard let sourceNode = node as? ContextExtractedContentContainingNode else { return } - let copyAction = { [weak self] in - guard let self else { return } - UIPasteboard.general.string = regDate - self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: i18n("Chat.RegDate.Copied", self.presentationData.strings.baseLanguageCode)), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) - } - var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: i18n("Chat.RegDate.Copy", self.presentationData.strings.baseLanguageCode), icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { c, _ in - c?.dismiss { copyAction() } - }))) - let actions = ContextController.Items(content: .list(items)) - let contextController = ContextController(presentationData: self.presentationData, source: .extracted(PeerInfoContextExtractedContentSource(sourceNode: sourceNode)), items: .single(actions), gesture: gesture) - self.controller?.present(contextController, in: .window(.root)) - } - private func openPhone(value: String, node: ASDisplayNode, gesture: ContextGesture?, progress: Promise?) { guard let sourceNode = node as? ContextExtractedContentContainingNode else { return