diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java
index 4c8e8e1a77..8e1dbf5366 100644
--- a/app/src/main/java/eu/faircode/email/Core.java
+++ b/app/src/main/java/eu/faircode/email/Core.java
@@ -4582,11 +4582,11 @@ class Core {
// Wearables
StringBuilder sb = new StringBuilder();
if (!TextUtils.isEmpty(message.subject))
- sb.append(message.subject);
+ sb.append(TextHelper.transliterate(context, message.subject));
if (wearable_preview && !TextUtils.isEmpty(preview)) {
if (sb.length() > 0)
sb.append(" - ");
- sb.append(preview);
+ sb.append(TextHelper.transliterate(context, preview));
}
if (sb.length() > 0)
mbuilder.setContentText(sb.toString());
@@ -4611,7 +4611,7 @@ class Core {
}
} else {
if (!TextUtils.isEmpty(message.subject))
- mbuilder.setContentText(message.subject);
+ mbuilder.setContentText(TextHelper.transliterate(context, message.subject));
}
if (info[0].hasPhoto())
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
index 450edec1dd..29bba0ee56 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
@@ -91,6 +91,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
private SwitchCompat swNotifyPreview;
private SwitchCompat swNotifyPreviewAll;
private SwitchCompat swNotifyPreviewOnly;
+ private SwitchCompat swNotifyTransliterate;
private ImageButton ibLight;
private SwitchCompat swWearablePreview;
private ImageButton ibWearable;
@@ -112,7 +113,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
"light", "sound",
"badge", "unseen_ignored",
"notify_background_only", "notify_known", "notify_summary", "notify_remove", "notify_clear",
- "notify_subtext", "notify_preview", "notify_preview_all", "notify_preview_only", "wearable_preview",
+ "notify_subtext", "notify_preview", "notify_preview_all", "notify_preview_only", "notify_transliterate",
+ "wearable_preview",
"notify_messaging",
"biometrics_notify",
"alert_once"
@@ -165,6 +167,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
swNotifyPreview = view.findViewById(R.id.swNotifyPreview);
swNotifyPreviewAll = view.findViewById(R.id.swNotifyPreviewAll);
swNotifyPreviewOnly = view.findViewById(R.id.swNotifyPreviewOnly);
+ swNotifyTransliterate = view.findViewById(R.id.swNotifyTransliterate);
ibLight = view.findViewById(R.id.ibLight);
swWearablePreview = view.findViewById(R.id.swWearablePreview);
ibWearable = view.findViewById(R.id.ibWearable);
@@ -439,6 +442,13 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
}
});
+ swNotifyTransliterate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("notify_transliterate", checked).apply();
+ }
+ });
+
ibLight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -489,6 +499,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
: R.color.lightColorBackground_cards));
}
+ swNotifyTransliterate.setVisibility(TextHelper.canTransliterate() ? View.VISIBLE : View.GONE);
swUnseenIgnored.setVisibility(Helper.isXiaomi() ? View.GONE : View.VISIBLE);
swAlertOnce.setVisibility(Helper.isXiaomi() || BuildConfig.DEBUG ? View.VISIBLE : View.GONE);
@@ -587,6 +598,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true));
swNotifyPreviewAll.setChecked(prefs.getBoolean("notify_preview_all", false));
swNotifyPreviewOnly.setChecked(prefs.getBoolean("notify_preview_only", false));
+ swNotifyTransliterate.setChecked(prefs.getBoolean("notify_transliterate", false));
swWearablePreview.setChecked(prefs.getBoolean("wearable_preview", false));
swMessagingStyle.setChecked(prefs.getBoolean("notify_messaging", false));
swBiometricsNotify.setChecked(prefs.getBoolean("biometrics_notify", true));
diff --git a/app/src/main/java/eu/faircode/email/Log.java b/app/src/main/java/eu/faircode/email/Log.java
index 68dc2a6148..f397442102 100644
--- a/app/src/main/java/eu/faircode/email/Log.java
+++ b/app/src/main/java/eu/faircode/email/Log.java
@@ -35,6 +35,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.sqlite.SQLiteFullException;
import android.graphics.Point;
+import android.icu.text.Transliterator;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
@@ -99,6 +100,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -1692,6 +1694,15 @@ public class Log {
.append(" yes=").append((uiMode & Configuration.UI_MODE_NIGHT_YES) != 0)
.append("\r\n");
+ if (BuildConfig.DEBUG &&
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ sb.append("Transliterators:");
+ Enumeration ids = Transliterator.getAvailableIDs();
+ while (ids.hasMoreElements())
+ sb.append(' ').append(ids.nextElement());
+ sb.append("\r\n");
+ }
+
try {
int maxKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES");
sb.append(context.getString(R.string.title_advanced_aes_key_size, maxKeySize)).append("\r\n");
diff --git a/app/src/main/java/eu/faircode/email/TextHelper.java b/app/src/main/java/eu/faircode/email/TextHelper.java
index 319c8d2f9e..2220b054ca 100644
--- a/app/src/main/java/eu/faircode/email/TextHelper.java
+++ b/app/src/main/java/eu/faircode/email/TextHelper.java
@@ -21,6 +21,8 @@ package eu.faircode.email;
import android.app.Person;
import android.content.Context;
+import android.content.SharedPreferences;
+import android.icu.text.Transliterator;
import android.os.Build;
import android.text.TextUtils;
import android.view.textclassifier.ConversationAction;
@@ -28,6 +30,9 @@ import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassifier;
+import androidx.preference.PreferenceManager;
+
+import java.text.Normalizer;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
@@ -82,6 +87,42 @@ public class TextHelper {
}
}
+ static boolean canTransliterate() {
+ if (!BuildConfig.DEBUG)
+ return false;
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
+ return false;
+
+ try {
+ Transliterator.getInstance("Any-Latin");
+ return true;
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
+
+ static String transliterate(Context context, String text) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
+ return text;
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean notify_transliterate = prefs.getBoolean("notify_transliterate", false);
+ if (!notify_transliterate)
+ return text;
+
+ try {
+ Transliterator t = Transliterator.getInstance("Any-Latin");
+ text = t.transliterate(text);
+ String normalized = Normalizer.normalize(text, Normalizer.Form.NFD);
+ text = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
+ } catch (Throwable ex) {
+ Log.w(ex);
+ }
+
+ return text;
+ }
+
static ConversationActions getConversationActions(
Context context, String[] texts, boolean replies, boolean outgoing, long time) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
diff --git a/app/src/main/res/layout/fragment_options_notifications.xml b/app/src/main/res/layout/fragment_options_notifications.xml
index df0a557300..1399b9d9d0 100644
--- a/app/src/main/res/layout/fragment_options_notifications.xml
+++ b/app/src/main/res/layout/fragment_options_notifications.xml
@@ -619,6 +619,17 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swNotifyPreviewOnly" />
+
+
Show message preview in notifications
Preview all text
Show notifications with a preview text only
+ Transliterate
Notification actions
Trash
Spam