From 493711c0cbbdc0785d1412c8ecb534beb2ccc609 Mon Sep 17 00:00:00 2001 From: UnnatiCP <129381063+unnaticleverpush@users.noreply.github.com> Date: Tue, 5 May 2026 10:22:34 +0530 Subject: [PATCH] feature/cp-11407-add-translation-feature-to-app-push-android Add support for topic name translations --- .../java/com/cleverpush/ChannelTopic.java | 67 ++++++++++++++++++- .../main/java/com/cleverpush/CleverPush.java | 25 ++++--- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/cleverpush/src/main/java/com/cleverpush/ChannelTopic.java b/cleverpush/src/main/java/com/cleverpush/ChannelTopic.java index 6c257acc..360f3f30 100644 --- a/cleverpush/src/main/java/com/cleverpush/ChannelTopic.java +++ b/cleverpush/src/main/java/com/cleverpush/ChannelTopic.java @@ -1,7 +1,12 @@ package com.cleverpush; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; import java.util.Map; +import org.json.JSONObject; + public class ChannelTopic { private String id; private String name; @@ -10,9 +15,11 @@ public class ChannelTopic { private String fcmBroadcastTopic; private String externalId; private Map customData; + private Boolean nameTranslationEnabled; + private Map nameTranslation; public ChannelTopic(String id, String name, String parentTopicId, Boolean defaultUnchecked, String fcmBroadcastTopic, - String externalId, Map customData) { + String externalId, Map customData, Boolean nameTranslationEnabled, Map nameTranslation) { this.id = id; this.name = name; this.parentTopicId = parentTopicId; @@ -20,6 +27,8 @@ public ChannelTopic(String id, String name, String parentTopicId, Boolean defaul this.fcmBroadcastTopic = fcmBroadcastTopic; this.externalId = externalId; this.customData = customData; + this.nameTranslationEnabled = nameTranslationEnabled; + this.nameTranslation = nameTranslation; } public String getId() { @@ -53,4 +62,60 @@ public Map getCustomData() { public String toString() { return this.getId(); } + + public Boolean getNameTranslationEnabled() { + return nameTranslationEnabled; + } + + public Map getNameTranslation() { + return nameTranslation; + } + + /** + * Parses {@code nameTranslation} from channel topic JSON into a map, or returns null if absent or invalid. + */ + public static Map parseNameTranslation(JSONObject topicObject) { + if (topicObject == null || !topicObject.has("nameTranslation")) { + return null; + } + try { + JSONObject translationObj = topicObject.optJSONObject("nameTranslation"); + if (translationObj == null) { + return null; + } + Map nameTranslationMap = new HashMap<>(); + Iterator keys = translationObj.keys(); + while (keys.hasNext()) { + String key = keys.next(); + nameTranslationMap.put(key, translationObj.optString(key)); + } + return nameTranslationMap; + } catch (Exception e) { + return null; + } + } + + /** + * Resolves the user-visible topic name: when {@code nameTranslationEnabled} is true, uses the device + * locale's language code to look up {@code nameTranslation}; otherwise or if no translation exists, uses {@code name}. + */ + public static String resolveLocalizedDisplayName(JSONObject topicObject) { + if (topicObject == null) { + return ""; + } + String name = topicObject.optString("name"); + if (!topicObject.optBoolean("nameTranslationEnabled", false)) { + return name; + } + Map translations = parseNameTranslation(topicObject); + if (translations == null || translations.isEmpty()) { + return name; + } + String language = Locale.getDefault().getLanguage(); + String translated = translations.get(language); + if (translated != null && !translated.isEmpty()) { + return translated; + } + return name; + } } diff --git a/cleverpush/src/main/java/com/cleverpush/CleverPush.java b/cleverpush/src/main/java/com/cleverpush/CleverPush.java index 98340f2d..bb49fe2d 100644 --- a/cleverpush/src/main/java/com/cleverpush/CleverPush.java +++ b/cleverpush/src/main/java/com/cleverpush/CleverPush.java @@ -2224,14 +2224,18 @@ private Set getAvailableTopicsFromConfig(JSONObject channelConfig) Logger.e(LOG_TAG, "Error parsing customData for topic.", e); } + Map nameTranslationMap = ChannelTopic.parseNameTranslation(topicObject); + ChannelTopic topic = new ChannelTopic( - topicObject.getString("_id"), - topicObject.optString("name"), - topicObject.optString("parentTopic", null), - topicObject.optBoolean("defaultUnchecked", false), - topicObject.optString("fcmBroadcastTopic", null), - topicObject.optString("externalId", null), - customData); + topicObject.getString("_id"), + topicObject.optString("name"), + topicObject.optString("parentTopic", null), + topicObject.optBoolean("defaultUnchecked", false), + topicObject.optString("fcmBroadcastTopic", null), + topicObject.optString("externalId", null), + customData, + topicObject.optBoolean("nameTranslationEnabled", false), + nameTranslationMap); topics.add(topic); } } @@ -3768,18 +3772,19 @@ private void updateTopicLastCheckedTime() { private String getTopicCheckboxText(JSONObject topic) { int oneHour = 60 * 60; int topicLastChecked = getTopicLastChecked(); + String displayName = ChannelTopic.resolveLocalizedDisplayName(topic); try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = simpleDateFormat.parse(topic.optString("createdAt")); int topicCreatedAt = (int) (date.getTime() / 1000); if (this.isSubscribed() && topicsDialogShowWhenNewAdded && topicLastChecked > 0 && topicCreatedAt + oneHour > topicLastChecked) { - return topic.optString("name") + " ●"; + return displayName + " ●"; } else { - return topic.optString("name"); + return displayName; } } catch (Exception e) { - return topic.optString("name"); + return displayName; } }