diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java
index 17c25630a9..4d3558697c 100644
--- a/app/src/main/java/eu/faircode/email/FragmentMessages.java
+++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java
@@ -304,6 +304,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
private boolean cards;
private boolean date;
+ private boolean date_fixed;
private boolean date_bold;
private boolean threading;
private boolean swipenav;
@@ -426,6 +427,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
swipenav = prefs.getBoolean("swipenav", true);
cards = prefs.getBoolean("cards", true);
date = prefs.getBoolean("date", true);
+ date_fixed = (!date && prefs.getBoolean("date_fixed", false));
date_bold = prefs.getBoolean("date_bold", false);
threading = (prefs.getBoolean("threading", true) ||
args.getBoolean("force_threading"));
@@ -663,18 +665,42 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
rvMessage.addItemDecoration(itemDecorator);
}
+ View inDate = view.findViewById(R.id.inDate);
+ TextView tvFixedDate = inDate.findViewById(R.id.tvDate);
+ View vSeparatorDate = inDate.findViewById(R.id.vSeparatorDate);
+
+ String sort = prefs.getString("sort", "time");
+ inDate.setVisibility(date_fixed && "time".equals(sort) ? View.INVISIBLE : View.GONE);
+ if (date_bold)
+ tvFixedDate.setTypeface(Typeface.DEFAULT_BOLD);
+
DividerItemDecoration dateDecorator = new DividerItemDecoration(getContext(), llm.getOrientation()) {
@Override
public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
- for (int i = 0; i < parent.getChildCount(); i++) {
+ int count = parent.getChildCount();
+ if (date_fixed)
+ if ("time".equals(adapter.getSort()))
+ inDate.setVisibility(count > 0 ? View.VISIBLE : View.INVISIBLE);
+ else
+ inDate.setVisibility(View.GONE);
+
+ for (int i = 0; i < count; i++) {
View view = parent.getChildAt(i);
int pos = parent.getChildAdapterPosition(view);
- View header = getView(view, parent, pos);
- if (header != null) {
- canvas.save();
- canvas.translate(0, parent.getChildAt(i).getTop() - header.getMeasuredHeight());
- header.draw(canvas);
- canvas.restore();
+
+ if (i == 0 && date_fixed && "time".equals(adapter.getSort())) {
+ TupleMessageEx top = adapter.getItemAtPosition(pos);
+ tvFixedDate.setVisibility(top == null ? View.GONE : View.VISIBLE);
+ vSeparatorDate.setVisibility(top == null || cards ? View.GONE : View.VISIBLE);
+ tvFixedDate.setText(top == null ? null : getRelativeDate(top.received, parent.getContext()));
+ } else {
+ View header = getView(view, parent, pos);
+ if (header != null) {
+ canvas.save();
+ canvas.translate(0, parent.getChildAt(i).getTop() - header.getMeasuredHeight());
+ header.draw(canvas);
+ canvas.restore();
+ }
}
}
}
@@ -690,7 +716,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
}
private View getView(View view, RecyclerView parent, int pos) {
- if (!date || !SORT_DATE_HEADER.contains(adapter.getSort()))
+ if (!date || !SORT_DATE_HEADER.contains(adapter.getSort()) || date_fixed)
return null;
if (pos == NO_POSITION)
@@ -716,7 +742,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
return null;
}
- View header = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_date, parent, false);
+ View header = inflater.inflate(R.layout.item_message_date, parent, false);
TextView tvDate = header.findViewById(R.id.tvDate);
tvDate.setTextSize(TypedValue.COMPLEX_UNIT_PX, Helper.getTextSize(parent.getContext(), adapter.getZoom()));
if (date_bold)
@@ -727,26 +753,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
vSeparatorDate.setVisibility(View.GONE);
}
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date());
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.DAY_OF_MONTH, -1);
- if (message.received <= cal.getTimeInMillis())
- tvDate.setText(
- DateUtils.formatDateRange(
- parent.getContext(),
- message.received,
- message.received,
- FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_DATE));
- else
- tvDate.setText(
- DateUtils.getRelativeTimeSpanString(
- message.received,
- new Date().getTime(),
- DAY_IN_MILLIS, 0));
+ tvDate.setText(getRelativeDate(message.received, parent.getContext()));
view.setContentDescription(tvDate.getText().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
@@ -758,6 +765,26 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
return header;
}
+
+ CharSequence getRelativeDate(long time, Context context) {
+ Date now = new Date();
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(now);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.add(Calendar.DAY_OF_MONTH, -1);
+
+ if (time <= cal.getTimeInMillis())
+ return DateUtils.formatDateRange(context,
+ time, time,
+ FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_DATE);
+ else
+ return DateUtils.getRelativeTimeSpanString(
+ time, now.getTime(),
+ DAY_IN_MILLIS, 0);
+ }
};
rvMessage.addItemDecoration(dateDecorator);
@@ -783,7 +810,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
boolean compact = prefs.getBoolean("compact", false);
int zoom = prefs.getInt("view_zoom", compact ? 0 : 1);
- String sort = prefs.getString("sort", "time");
boolean ascending = prefs.getBoolean(
viewType == AdapterMessage.ViewType.THREAD ? "ascending_thread" : "ascending_list", false);
boolean filter_duplicates = prefs.getBoolean("filter_duplicates", true);
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java
index 9de78c315b..a70c685799 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptions.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java
@@ -127,7 +127,7 @@ public class FragmentOptions extends FragmentBase {
"send_pending",
"startup", "cards", "beige", "tabular_card_bg", "shadow_unread",
"portrait2", "portrait2c", "landscape", "nav_count", "navbar_colorize",
- "indentation", "date", "date_bold", "threading", "threading_unread",
+ "indentation", "date", "date_fixed", "date_bold", "threading", "threading_unread",
"highlight_unread", "highlight_color", "color_stripe",
"avatars", "bimi", "gravatars", "favicons", "generated_icons", "identicons", "circular", "saturation", "brightness", "threshold",
"email_format", "prefer_contact", "only_contact", "distinguish_contacts", "show_recipients",
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java
index 721c2b5045..76c9d54fc0 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java
@@ -64,6 +64,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
private SwitchCompat swTabularBackground;
private SwitchCompat swShadow;
private SwitchCompat swDate;
+ private SwitchCompat swDateFixed;
private SwitchCompat swDateBold;
private SwitchCompat swNavBarColorize;
private SwitchCompat swPortrait2;
@@ -154,7 +155,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
private final static String[] RESET_OPTIONS = new String[]{
"theme", "startup", "cards", "beige", "tabular_card_bg", "shadow_unread",
- "date", "date_bold",
+ "date", "date_fixed", "date_bold",
"portrait2", "portrait2c", "landscape", "nav_options", "nav_count", "navbar_colorize",
"threading", "threading_unread", "indentation", "seekbar", "actionbar", "actionbar_color",
"highlight_unread", "highlight_color", "color_stripe",
@@ -188,6 +189,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
swTabularBackground = view.findViewById(R.id.swTabularCardBackground);
swShadow = view.findViewById(R.id.swShadow);
swDate = view.findViewById(R.id.swDate);
+ swDateFixed = view.findViewById(R.id.swDateFixed);
swDateBold = view.findViewById(R.id.swDateBold);
swPortrait2 = view.findViewById(R.id.swPortrait2);
swPortrait2c = view.findViewById(R.id.swPortrait2c);
@@ -334,7 +336,16 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("date", checked).apply();
- swDateBold.setEnabled(checked);
+ swDateFixed.setEnabled(!checked);
+ swDateBold.setEnabled(checked || swDateFixed.isChecked());
+ }
+ });
+
+ swDateFixed.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("date_fixed", checked).apply();
+ swDateBold.setEnabled(swDate.isChecked() || checked);
}
});
@@ -1029,8 +1040,10 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
swTabularBackground.setEnabled(!swCards.isChecked());
swShadow.setEnabled(swCards.isChecked());
swDate.setChecked(prefs.getBoolean("date", true));
+ swDateFixed.setChecked(prefs.getBoolean("date_fixed", false));
+ swDateFixed.setEnabled(!swDate.isChecked());
swDateBold.setChecked(prefs.getBoolean("date_bold", false));
- swDateBold.setEnabled(swDate.isChecked());
+ swDateBold.setEnabled(swDate.isChecked() || swDateFixed.isChecked());
swPortrait2.setChecked(prefs.getBoolean("portrait2", false));
swPortrait2c.setChecked(prefs.getBoolean("portrait2c", false) && !swPortrait2.isChecked());
swLandscape.setChecked(prefs.getBoolean("landscape", true));
diff --git a/app/src/main/res/layout/fragment_messages.xml b/app/src/main/res/layout/fragment_messages.xml
index 3a11cfc8df..7ebb57cc4b 100644
--- a/app/src/main/res/layout/fragment_messages.xml
+++ b/app/src/main/res/layout/fragment_messages.xml
@@ -135,6 +135,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvHintSelect" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/inDate" />
+
+
Use card color as background color when using tabular style
Use shadow for unread messages when using card style
Group by date
+ Show fixed date header at the top
Show date in bold
Conversation threading
Show number of unread messages in conversations