From 0a6e0f1db1f52e31a3fcb77bcff6bf7b2ce947f7 Mon Sep 17 00:00:00 2001 From: ROCKET Date: Tue, 24 Feb 2026 13:35:19 -0600 Subject: [PATCH] Fix translated text links and adjust provider lists --- .../translator/SpaceGramTranslator.java | 25 ++++ .../translator/TranslationHelper.java | 112 +++++++++++++++++- .../ui/SpaceGramGeneralSettingsActivity.java | 4 +- .../ui/Components/TranslateButton.java | 13 +- 4 files changed, 136 insertions(+), 18 deletions(-) diff --git a/TMessagesProj/src/main/java/org/spacegram/translator/SpaceGramTranslator.java b/TMessagesProj/src/main/java/org/spacegram/translator/SpaceGramTranslator.java index 2d8527e1d6a..fbd5f5f2a2f 100644 --- a/TMessagesProj/src/main/java/org/spacegram/translator/SpaceGramTranslator.java +++ b/TMessagesProj/src/main/java/org/spacegram/translator/SpaceGramTranslator.java @@ -33,6 +33,8 @@ public static SpaceGramTranslator getInstance() { public static String getProviderName(int provider) { switch (provider) { + case 0: + return "Telegram"; case PROVIDER_GOOGLE: return "Google Translate"; case PROVIDER_MYMEMORY: @@ -48,6 +50,29 @@ public static String getProviderName(int provider) { } } + + public static String[] getAllProviderNamesWithTelegram() { + return new String[]{ + "Telegram", + "Google Translate", + "MyMemory", + "Bing", + "Baidu (CN)", + "Yandex (RU)" + }; + } + + public static int[] getAllProviderIdsWithTelegram() { + return new int[]{ + 0, + PROVIDER_GOOGLE, + PROVIDER_MYMEMORY, + PROVIDER_BING, + PROVIDER_BAIDU, + PROVIDER_YANDEX + }; + } + public static String[] getAllProviderNames() { return new String[]{ "Google Translate", diff --git a/TMessagesProj/src/main/java/org/spacegram/translator/TranslationHelper.java b/TMessagesProj/src/main/java/org/spacegram/translator/TranslationHelper.java index 0f5a5a5bf2f..20d9025658b 100644 --- a/TMessagesProj/src/main/java/org/spacegram/translator/TranslationHelper.java +++ b/TMessagesProj/src/main/java/org/spacegram/translator/TranslationHelper.java @@ -9,6 +9,10 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.tgnet.TLRPC; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + /** * Helper class to handle translation based on SpaceGramConfig.translateStyle. */ @@ -92,8 +96,9 @@ private static void translateInline( int currentAccount, Runnable onComplete ) { + final LinkMaskedText linkMaskedText = maskLinks(text, messageObject.messageOwner.entities); SpaceGramTranslator.getInstance().translate( - text, + linkMaskedText.maskedText, fromLang, toLang, (result, rateLimit) -> AndroidUtilities.runOnUIThread(() -> { @@ -103,9 +108,7 @@ private static void translateInline( TLRPC.TL_textWithEntities translatedText = new TLRPC.TL_textWithEntities(); - translatedText.text = result; - translatedText.entities = - messageObject.messageOwner.entities; + translatedText.text = restorePlaceholders(result, linkMaskedText.placeholders, translatedText.entities = new ArrayList<>()); messageObject.messageOwner.translatedText = translatedText; @@ -130,6 +133,107 @@ private static void translateInline( ); } + private static class LinkPlaceholder { + final String token; + final String visibleText; + final String url; + final boolean textUrl; + + LinkPlaceholder(String token, String visibleText, String url, boolean textUrl) { + this.token = token; + this.visibleText = visibleText; + this.url = url; + this.textUrl = textUrl; + } + } + + private static class LinkMaskedText { + final String maskedText; + final ArrayList placeholders; + + LinkMaskedText(String maskedText, ArrayList placeholders) { + this.maskedText = maskedText; + this.placeholders = placeholders; + } + } + + private static LinkMaskedText maskLinks(String text, ArrayList entities) { + if (TextUtils.isEmpty(text) || entities == null || entities.isEmpty()) { + return new LinkMaskedText(text, new ArrayList<>()); + } + + ArrayList linkEntities = new ArrayList<>(); + for (int i = 0; i < entities.size(); i++) { + TLRPC.MessageEntity entity = entities.get(i); + if (entity == null) { + continue; + } + if (entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntityUrl) { + linkEntities.add(entity); + } + } + if (linkEntities.isEmpty()) { + return new LinkMaskedText(text, new ArrayList<>()); + } + + Collections.sort(linkEntities, Comparator.comparingInt(e -> e.offset)); + StringBuilder builder = new StringBuilder(); + ArrayList placeholders = new ArrayList<>(); + int cursor = 0; + int tokenIndex = 0; + for (int i = 0; i < linkEntities.size(); i++) { + TLRPC.MessageEntity entity = linkEntities.get(i); + int start = Math.max(0, entity.offset); + int end = Math.min(text.length(), entity.offset + entity.length); + if (start < cursor || end <= start) { + continue; + } + builder.append(text, cursor, start); + String token = "__SG_LINK_" + tokenIndex++ + "__"; + String visibleText = text.substring(start, end); + String url = entity instanceof TLRPC.TL_messageEntityTextUrl ? entity.url : visibleText; + placeholders.add(new LinkPlaceholder(token, visibleText, url, entity instanceof TLRPC.TL_messageEntityTextUrl)); + builder.append(token); + cursor = end; + } + builder.append(text, cursor, text.length()); + return new LinkMaskedText(builder.toString(), placeholders); + } + + private static String restorePlaceholders(String translatedText, ArrayList placeholders, ArrayList outputEntities) { + if (TextUtils.isEmpty(translatedText) || placeholders == null || placeholders.isEmpty()) { + return translatedText; + } + + String restored = translatedText; + for (int i = 0; i < placeholders.size(); i++) { + LinkPlaceholder placeholder = placeholders.get(i); + int start = restored.indexOf(placeholder.token); + if (start < 0) { + continue; + } + String replacement = placeholder.visibleText; + restored = restored.substring(0, start) + replacement + restored.substring(start + placeholder.token.length()); + + if (!TextUtils.isEmpty(placeholder.url) && outputEntities != null) { + if (placeholder.textUrl) { + TLRPC.TL_messageEntityTextUrl entity = new TLRPC.TL_messageEntityTextUrl(); + entity.offset = start; + entity.length = replacement.length(); + entity.url = placeholder.url; + outputEntities.add(entity); + } else { + TLRPC.TL_messageEntityUrl entity = new TLRPC.TL_messageEntityUrl(); + entity.offset = start; + entity.length = replacement.length(); + outputEntities.add(entity); + } + } + } + + return restored; + } + /** * Check if a message is currently translated. */ diff --git a/TMessagesProj/src/main/java/org/spacegram/ui/SpaceGramGeneralSettingsActivity.java b/TMessagesProj/src/main/java/org/spacegram/ui/SpaceGramGeneralSettingsActivity.java index f88c7fbed61..b0e7fc40955 100644 --- a/TMessagesProj/src/main/java/org/spacegram/ui/SpaceGramGeneralSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/spacegram/ui/SpaceGramGeneralSettingsActivity.java @@ -97,8 +97,8 @@ private void onClick(UItem item, View view, int position, float x, float y) { } private void showProviderSelector() { - final String[] providerNames = SpaceGramTranslator.getAllProviderNames(); - final int[] providerIds = SpaceGramTranslator.getAllProviderIds(); + final String[] providerNames = SpaceGramTranslator.getAllProviderNamesWithTelegram(); + final int[] providerIds = SpaceGramTranslator.getAllProviderIdsWithTelegram(); // Find current provider index int currentIndex = -1; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java index d922bb18276..2a23da5c1fc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java @@ -353,7 +353,7 @@ protected void dispatchDraw(Canvas canvas) { ActionBarMenuSubItem providerButton = new ActionBarMenuSubItem(getContext(), true, false, resourcesProvider); providerButton.setTextAndIcon(getString(R.string.SettingsSpaceGramTranslatorProvider), R.drawable.msg_customize); - providerButton.setSubtext(SpaceGramConfig.translateProvider == 0 ? "Telegram" : SpaceGramTranslator.getProviderName(SpaceGramConfig.translateProvider)); + providerButton.setSubtext(SpaceGramTranslator.getProviderName(SpaceGramConfig.translateProvider)); providerButton.setItemHeight(56); popupLayout.addView(providerButton); @@ -366,17 +366,6 @@ protected void dispatchDraw(Canvas canvas) { providerBackButton.setOnClickListener(e -> popupLayout.getSwipeBack().closeForeground()); providerSwipeBack.addView(providerBackButton); - ActionBarMenuSubItem telegramProvider = new ActionBarMenuSubItem(getContext(), 2, false, false, resourcesProvider); - telegramProvider.setText("Telegram"); - telegramProvider.setChecked(SpaceGramConfig.translateProvider == 0); - telegramProvider.setOnClickListener(e -> { - SpaceGramConfig.translateProvider = 0; - SpaceGramConfig.saveConfig(); - popupWindow.dismiss(); - updateText(); - }); - providerSwipeBack.addView(telegramProvider); - int[] providerIds = SpaceGramTranslator.getAllProviderIds(); String[] providerNames = SpaceGramTranslator.getAllProviderNames(); for (int i = 0; i < providerIds.length; i++) {