From e6970faf6ef8644a29080ba9710047fae5eb0f37 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 3 Nov 2018 16:34:35 +0000 Subject: [PATCH] Added identicons --- FAQ.md | 1 - .../java/eu/faircode/email/ActivityBase.java | 3 +- .../eu/faircode/email/AdapterMessage.java | 28 ++++++++++--- .../eu/faircode/email/FragmentOptions.java | 10 +++++ .../java/eu/faircode/email/FragmentSetup.java | 1 + .../java/eu/faircode/email/Identicon.java | 42 +++++++++++++++++++ app/src/main/res/layout/fragment_options.xml | 11 ++++- app/src/main/res/values/strings.xml | 1 + 8 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/eu/faircode/email/Identicon.java diff --git a/FAQ.md b/FAQ.md index d2f71bebcc..057328787b 100644 --- a/FAQ.md +++ b/FAQ.md @@ -14,7 +14,6 @@ Frequently requested features: * Executing filter rules: filter rules should be executed on the server because a battery powered device with possibly an unstable internet connection is not suitable for this. * Widget to read e-mail: widgets do not allow user interaction, so a widget to read e-mail would not be very useful. * Swipe left/right to go to previous/next message: swiping also selects message text, so this would not work reliably. -* Generate avatars: you can use [Micopi+](https://f-droid.org/en/packages/com.easytarget.micopi/) or a similar app to generate images for your contacts. Since FairEmail is meant to be privacy friendly, the following will not be added: diff --git a/app/src/main/java/eu/faircode/email/ActivityBase.java b/app/src/main/java/eu/faircode/email/ActivityBase.java index 4a7dd98f3b..f3c503c883 100644 --- a/app/src/main/java/eu/faircode/email/ActivityBase.java +++ b/app/src/main/java/eu/faircode/email/ActivityBase.java @@ -81,7 +81,8 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc finish(); if (this.getClass().equals(ActivitySetup.class)) startActivity(getIntent()); - } else if (!this.getClass().equals(ActivitySetup.class) && ("compact".equals(key) || "debug".equals(key))) + } else if (!this.getClass().equals(ActivitySetup.class) && + ("avatars".equals(key) || "identicons".equals(key) || "compact".equals(key) || "debug".equals(key))) finish(); } diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 29a8577580..b2d7e04dee 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -26,6 +26,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -112,9 +113,12 @@ public class AdapterMessage extends PagedListAdapter selectionTracker = null; private DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG); @@ -276,14 +280,23 @@ public class AdapterMessage extends PagedListAdapter 0) + ivAvatar.setImageBitmap(Identicon.generate(((InternetAddress) message.from[0]).getAddress(), dp24, 5)); + else + ivAvatar.setImageDrawable(null); + photo = true; + } ivAvatar.setVisibility(photo ? View.VISIBLE : View.GONE); vwColor.setBackgroundColor(message.accountColor == null ? Color.TRANSPARENT : message.accountColor); @@ -1391,8 +1404,11 @@ public class AdapterMessage extends PagedListAdapter DIFF_CALLBACK = diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 028a5f0c78..490df589a2 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -34,6 +34,7 @@ import androidx.appcompat.widget.SwitchCompat; public class FragmentOptions extends FragmentEx { private SwitchCompat swEnabled; private SwitchCompat swAvatars; + private SwitchCompat swIdenticons; private SwitchCompat swLight; private SwitchCompat swBrowse; private SwitchCompat swSwipe; @@ -52,6 +53,7 @@ public class FragmentOptions extends FragmentEx { // Get controls swEnabled = view.findViewById(R.id.swEnabled); swAvatars = view.findViewById(R.id.swAvatars); + swIdenticons = view.findViewById(R.id.swIdenticons); swLight = view.findViewById(R.id.swLight); swBrowse = view.findViewById(R.id.swBrowse); swSwipe = view.findViewById(R.id.swSwipe); @@ -84,6 +86,14 @@ public class FragmentOptions extends FragmentEx { } }); + swIdenticons.setChecked(prefs.getBoolean("identicons", true)); + swIdenticons.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("identicons", checked).apply(); + } + }); + swLight.setChecked(prefs.getBoolean("light", false)); swLight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentSetup.java b/app/src/main/java/eu/faircode/email/FragmentSetup.java index 65d35e893b..b05f948c96 100644 --- a/app/src/main/java/eu/faircode/email/FragmentSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentSetup.java @@ -107,6 +107,7 @@ public class FragmentSetup extends FragmentEx { static final List EXPORT_SETTINGS = Arrays.asList( "enabled", "avatars", + "identicons", "light", "browse", "swipe", diff --git a/app/src/main/java/eu/faircode/email/Identicon.java b/app/src/main/java/eu/faircode/email/Identicon.java new file mode 100644 index 0000000000..46a161d79e --- /dev/null +++ b/app/src/main/java/eu/faircode/email/Identicon.java @@ -0,0 +1,42 @@ +package eu.faircode.email; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +class Identicon { + static Bitmap generate(String email, int size, int pixels) { + byte[] hash; + try { + hash = MessageDigest.getInstance("MD5").digest(email.getBytes()); + } catch (NoSuchAlgorithmException ignored) { + hash = email.getBytes(); + } + + Paint paint = new Paint(); + paint.setColor(Color.argb(255, hash[0], hash[1], hash[2])); + + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + canvas.drawColor(Color.argb(255, 128, 128, 128)); + + float psize = (float) size / pixels; + + for (int x = 0; x < pixels; x++) { + int i = (x > pixels / 2 ? pixels - x - 1 : x); + for (int y = 0; y < pixels; y++) { + if ((hash[i] >> y & 1) == 1) { + RectF rect = new RectF(x * psize, y * psize, (x + 1) * psize, (y + 1) * psize); + canvas.drawRect(rect, paint); + } + } + } + + return bitmap; + } +} diff --git a/app/src/main/res/layout/fragment_options.xml b/app/src/main/res/layout/fragment_options.xml index 0eaa9c893d..b425008e12 100644 --- a/app/src/main/res/layout/fragment_options.xml +++ b/app/src/main/res/layout/fragment_options.xml @@ -29,6 +29,15 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/swEnabled" /> + + + app:layout_constraintTop_toBottomOf="@id/swIdenticons" /> Advanced options Enabled Show contact photos + Show identicons Use notification light Browse messages on the server Swipe actions