diff --git a/Telegram/Telegram-iOS/Resources/Cocoon.tgs b/Telegram/Telegram-iOS/Resources/Cocoon.tgs new file mode 100644 index 0000000000..9eba8213ad Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/Cocoon.tgs differ diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 95f37268bc..f1b37aa6fb 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -15648,3 +15648,5 @@ Error: %8$@"; "CocoonInfo.ForEveryone.Text" = "Any developer can use Cocoon for AI features. Learn more at [@cocoon](telegram) or [cocoon.org](web)."; "CocoonInfo.IntergrateInfo" = "Want to integrate Cocoon into your projects?\nReach out at [t.me/cocoon?direct]()"; "CocoonInfo.Understood" = "Understood"; + +"Conversation.Translation.CocoonInfo" = "Translations are powered by\n**#Cocoon**. [How does it work?]()"; diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift index 1cdc2775e3..a2b2b79f37 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift @@ -767,7 +767,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr self.panelButton = panelButton } - let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: params.bottomInset, innerDiameter: 52.0 * 0.5, sideInset: sideInset + 16.0) + let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: params.bottomInset, innerDiameter: 52.0 * 0.5, sideInset: sideInset + 30.0) let buttonTitle: String var buttonIconName: String? diff --git a/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift b/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift index 9905cf01c1..56125028e5 100644 --- a/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift +++ b/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift @@ -17,6 +17,8 @@ import TranslateUI import TelegramUIPreferences import TelegramNotices import PremiumUI +import LocalMediaResources +import AppBundle final class ChatTranslationPanelNode: ASDisplayNode { private let context: AccountContext @@ -362,11 +364,40 @@ final class ChatTranslationPanelNode: ASDisplayNode { self?.close() }))) + items.append(.separator) + + let cocoonPath = getAppBundle().url(forResource: "Cocoon", withExtension: "tgs")?.path ?? "" + let cocoonFile = TelegramMediaFile( + fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: -123456789), + partialReference: nil, + resource: BundleResource(name: "Cocoon", path: cocoonPath), + previewRepresentations: [], + videoThumbnails: [], + immediateThumbnailData: nil, + mimeType: "application/x-tgsticker", + size: nil, + attributes: [ + .FileName(fileName: "sticker.tgs"), + .CustomEmoji(isPremium: false, isSingleColor: true, alt: "", packReference: .animatedEmojiAnimations) + ], + alternativeRepresentations: [] + ) + + let (cocoonText, entities) = parseCocoonMenuTextEntities(presentationData.strings.Conversation_Translation_CocoonInfo, emojiFileId: cocoonFile.fileId.id) + items.append(.action(ContextMenuActionItem(text: cocoonText, entities: entities, entityFiles: [cocoonFile.fileId.id: cocoonFile], enableEntityAnimations: true, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: { [weak self] c, _ in + c?.dismiss(completion: nil) + + if let controller = self?.controller() { + let infoController = context.sharedContext.makeCocoonInfoScreen(context: context) + controller.push(infoController) + } + }))) + return ContextController.Items(content: .list(items)) } if let controller = self.controller() { - let contextController = ContextController(presentationData: presentationData, source: .reference(TranslationContextReferenceContentSource(controller: controller, sourceNode: node)), items: items, gesture: gesture) + let contextController = ContextController(context: context, presentationData: presentationData, source: .reference(TranslationContextReferenceContentSource(controller: controller, sourceNode: node)), items: items, gesture: gesture) controller.presentInGlobalOverlay(contextController) } } @@ -941,3 +972,116 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte ) } } + +private func parseCocoonMenuTextEntities(_ input: String, emojiFileId: Int64) -> (String, [MessageTextEntity]) { + var output = "" + + var entities: [MessageTextEntity] = [] + + var i = input.startIndex + var outputCount = 0 + + func utf16Len(_ s: String) -> Int { + s.utf16.count + } + + func peek(_ offset: Int) -> Character? { + var idx = i + for _ in 0.. start { + entities.append(MessageTextEntity(range: start.. start { + entities.append(MessageTextEntity(range: start..