From ee6664ce9d4c25e93b8952126fb59c64c1b88922 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 11 Feb 2021 12:27:09 -0300 Subject: [PATCH] Show actual auto-delete timer duration in UI (only days and hours for now) --- .../ConversationItemViewHolder.java | 21 ++-- .../briar/android/util/UiUtils.java | 24 ++++ briar-android/src/main/res/values/strings.xml | 16 ++- .../util/UiUtilsFormatDurationTest.java | 111 ++++++++++++++++++ 4 files changed, 160 insertions(+), 12 deletions(-) create mode 100644 briar-android/src/test/java/org/briarproject/briar/android/util/UiUtilsFormatDurationTest.java diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationItemViewHolder.java index 72b331971..c09a2cbf7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationItemViewHolder.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationItemViewHolder.java @@ -18,6 +18,7 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; import static org.briarproject.bramble.util.StringUtils.trim; import static org.briarproject.briar.android.util.UiUtils.formatDate; +import static org.briarproject.briar.android.util.UiUtils.formatDuration; import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; @UiThread @@ -82,19 +83,23 @@ abstract class ConversationItemViewHolder extends ViewHolder { Context ctx = itemView.getContext(); topNotice.setVisibility(VISIBLE); boolean enabled = item.getAutoDeleteTimer() != NO_AUTO_DELETE_TIMER; + String duration = enabled ? + formatDuration(ctx, item.getAutoDeleteTimer()) : ""; String tapToLearnMore = ctx.getString(R.string.tap_to_learn_more); String text; if (item.isIncoming()) { String name = item.getContactName().getValue(); - int strRes = enabled ? - R.string.auto_delete_msg_contact_enabled : - R.string.auto_delete_msg_contact_disabled; - text = ctx.getString(strRes, name, tapToLearnMore); + text = enabled ? + ctx.getString(R.string.auto_delete_msg_contact_enabled, + name, duration, tapToLearnMore) : + ctx.getString(R.string.auto_delete_msg_contact_disabled, + name, tapToLearnMore); } else { - int strRes = enabled ? - R.string.auto_delete_msg_you_enabled : - R.string.auto_delete_msg_you_disabled; - text = ctx.getString(strRes, tapToLearnMore); + text = enabled ? + ctx.getString(R.string.auto_delete_msg_you_enabled, + duration, tapToLearnMore) : + ctx.getString(R.string.auto_delete_msg_you_disabled, + tapToLearnMore); } topNotice.setText(text); topNotice.setOnClickListener( diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index 50459bb78..26b1e3fe8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -6,6 +6,7 @@ import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface.OnClickListener; import android.content.Intent; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.PowerManager; @@ -75,6 +76,7 @@ import static android.text.format.DateUtils.FORMAT_ABBREV_TIME; import static android.text.format.DateUtils.FORMAT_SHOW_DATE; import static android.text.format.DateUtils.FORMAT_SHOW_TIME; import static android.text.format.DateUtils.FORMAT_SHOW_YEAR; +import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static android.text.format.DateUtils.YEAR_IN_MILLIS; @@ -166,6 +168,28 @@ public class UiUtils { return DateUtils.formatDateTime(ctx, time, flags); } + /** + * Returns the given duration in a human-friendly format. For example, + * "7 days" or "1 hour". Returns only the largest meaningful unit of time, + * from days up to hours. + */ + public static String formatDuration(Context ctx, long millis) { + Resources r = ctx.getResources(); + if (millis >= DAY_IN_MILLIS) { + int days = (int) (millis / DAY_IN_MILLIS); + int rest = (int) (millis % DAY_IN_MILLIS); + String dayStr = + r.getQuantityString(R.plurals.duration_days, days, days); + if (rest < HOUR_IN_MILLIS / 2) return dayStr; + else return dayStr + " " + formatDuration(ctx, rest); + } else { + int hours = (int) ((millis + HOUR_IN_MILLIS / 2) / HOUR_IN_MILLIS); + // anything less than one hour is shown as one hour + if (hours < 1) hours = 1; + return r.getQuantityString(R.plurals.duration_hours, hours, hours); + } + } + public static long getDaysUntilExpiry() { long now = System.currentTimeMillis(); return (EXPIRY_DATE - now) / DAYS.toMillis(1); diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index f684c7d06..fea7e7af0 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -168,12 +168,20 @@ Change contact name Contact name Disappearing messages - - Your messages will disappear after 7 days. %1$s + + Your messages will disappear after %1$s. %2$s Your messages will not disappear. %1$s - - %1$s\'s messages will disappear after 7 days. %2$s + + %1$s\'s messages will disappear after %2$s. %3$s + + %d hour + %d hours + + + %d day + %d days + %1$s\'s messages will not disappear. %2$s Tap to learn more. diff --git a/briar-android/src/test/java/org/briarproject/briar/android/util/UiUtilsFormatDurationTest.java b/briar-android/src/test/java/org/briarproject/briar/android/util/UiUtilsFormatDurationTest.java new file mode 100644 index 000000000..eb056cf56 --- /dev/null +++ b/briar-android/src/test/java/org/briarproject/briar/android/util/UiUtilsFormatDurationTest.java @@ -0,0 +1,111 @@ +package org.briarproject.briar.android.util; + +import android.content.Context; +import android.content.res.Resources; + +import org.briarproject.bramble.test.BrambleMockTestCase; +import org.briarproject.briar.R; +import org.jmock.Expectations; +import org.jmock.lib.legacy.ClassImposteriser; +import org.junit.Test; + +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.briarproject.briar.android.util.UiUtils.formatDuration; + +public class UiUtilsFormatDurationTest extends BrambleMockTestCase { + + private final Context ctx; + private final Resources r; + private final int strHours = R.plurals.duration_hours; + private final int strDays = R.plurals.duration_days; + + public UiUtilsFormatDurationTest() { + context.setImposteriser(ClassImposteriser.INSTANCE); + ctx = context.mock(Context.class); + r = context.mock(Resources.class); + } + + @Test + public void testOneHour() { + expectHourString(1); + formatDuration(ctx, HOURS.toMillis(1)); + } + + @Test + public void testOneDay() { + expectDayString(1); + formatDuration(ctx, DAYS.toMillis(1)); + } + + @Test + public void test10Minutes() { + expectHourString(1); + formatDuration(ctx, MINUTES.toMillis(10)); + } + + @Test + public void testSevenDays() { + expectDayString(7); + formatDuration(ctx, DAYS.toMillis(7)); + } + + @Test + public void testSevenDays2Hours() { + expectDayString(7); + expectHourString(2); + formatDuration(ctx, DAYS.toMillis(7) + HOURS.toMillis(2)); + } + + @Test + public void testSevenDays20Minutes() { + expectDayString(7); + formatDuration(ctx, DAYS.toMillis(7) + MINUTES.toMillis(20)); + } + + @Test + public void testSevenDays40Minutes() { + expectDayString(7); + expectHourString(1); + formatDuration(ctx, DAYS.toMillis(7) + MINUTES.toMillis(40)); + } + + @Test + public void testTwoDays11Hours() { + expectDayString(2); + expectHourString(11); + formatDuration(ctx, DAYS.toMillis(2) + HOURS.toMillis(11)); + } + + @Test + public void testTwoDays12Hours() { + expectDayString(2); + expectHourString(12); + formatDuration(ctx, DAYS.toMillis(2) + HOURS.toMillis(12)); + } + + @Test + public void testTwoDays13Hours() { + expectDayString(2); + expectHourString(13); + formatDuration(ctx, DAYS.toMillis(2) + HOURS.toMillis(13)); + } + + private void expectHourString(int hours) { + context.checking(new Expectations() {{ + oneOf(ctx).getResources(); + will(returnValue(r)); + oneOf(r).getQuantityString(strHours, hours, hours); + }}); + } + + private void expectDayString(int days) { + context.checking(new Expectations() {{ + oneOf(ctx).getResources(); + will(returnValue(r)); + oneOf(r).getQuantityString(strDays, days, days); + }}); + } + +}