Added option to delay automatically marking messages as read

This commit is contained in:
M66B 2024-01-07 09:26:58 +01:00
parent c6961a1c06
commit e6f8f3e558
7 changed files with 97 additions and 19 deletions

View File

@ -8,6 +8,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added option to to delay automatically marking messages as read
* Replaced [javadns](https://github.com/dnsjava/dnsjava) by [MiniDNS](https://github.com/MiniDNS/minidns)
* Added account/identity option to enforce DNSSEC
* Added account/identity option to enforce DANE, see [the FAQ](https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq202)

View File

@ -8,6 +8,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added option to to delay automatically marking messages as read
* Replaced [javadns](https://github.com/dnsjava/dnsjava) by [MiniDNS](https://github.com/MiniDNS/minidns)
* Added account/identity option to enforce DNSSEC
* Added account/identity option to enforce DANE, see [the FAQ](https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq202)

View File

@ -340,6 +340,7 @@ public class FragmentMessages extends FragmentBase
private int actionbar_delete_id;
private int actionbar_archive_id;
private boolean actionbar_color;
private int seen_delay = 0;
private boolean autoexpand;
private boolean autoclose;
private String onclose;
@ -493,6 +494,7 @@ public class FragmentMessages extends FragmentBase
actionbar_delete_id = (actionbar_swap ? R.id.action_archive : R.id.action_delete);
actionbar_archive_id = (actionbar_swap ? R.id.action_delete : R.id.action_archive);
actionbar_color = prefs.getBoolean("actionbar_color", false);
seen_delay = prefs.getInt("seen_delay", 0);
autoexpand = prefs.getBoolean("autoexpand", true);
autoclose = prefs.getBoolean("autoclose", true);
onclose = (autoclose ? null : prefs.getString("onclose", null));
@ -2546,7 +2548,7 @@ public class FragmentMessages extends FragmentBase
@Override
public void setExpanded(TupleMessageEx message, boolean value, boolean scroll) {
// Prevent flicker
if (value && message.accountAutoSeen &&
if (value && message.accountAutoSeen && seen_delay == 0 &&
(message.uid != null || message.accountProtocol == EntityAccount.TYPE_POP)) {
message.unseen = 0;
message.ui_seen = true;
@ -7601,13 +7603,11 @@ public class FragmentMessages extends FragmentBase
}
private void handleExpand(long id) {
Bundle args = new Bundle();
args.putLong("id", id);
new SimpleTask<Void>() {
SimpleTask<Void> taskExpand = new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean seen = args.getBoolean("seen");
Long reload = null;
@ -7630,19 +7630,24 @@ public class FragmentMessages extends FragmentBase
if (!"connected".equals(account.state) && !account.isTransient(context))
reload = account.id;
if (message.ui_unsnoozed)
db.message().setMessageUnsnoozed(message.id, false);
if (seen) {
if (message.ui_unsnoozed)
db.message().setMessageUnsnoozed(message.id, false);
if (!account.auto_seen && !message.ui_ignored && message.ui_snoozed == null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean notify_remove = prefs.getBoolean("notify_remove", true);
if (notify_remove)
db.message().setMessageUiIgnored(message.id, true);
if (!account.auto_seen && !message.ui_ignored && message.ui_snoozed == null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean notify_remove = prefs.getBoolean("notify_remove", true);
if (notify_remove)
db.message().setMessageUiIgnored(message.id, true);
}
if (account.protocol != EntityAccount.TYPE_IMAP || message.uid != null) {
if (account.auto_seen)
EntityOperation.queue(context, message, EntityOperation.SEEN, true);
}
}
if (account.protocol != EntityAccount.TYPE_IMAP || message.uid != null) {
if (account.auto_seen)
EntityOperation.queue(context, message, EntityOperation.SEEN, true);
if (!message.content)
EntityOperation.queue(context, message, EntityOperation.BODY);
}
@ -7664,7 +7669,27 @@ public class FragmentMessages extends FragmentBase
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.setLog(false).execute(this, args, "messages:expand");
}.setLog(false);
Bundle args = new Bundle();
args.putLong("id", id);
args.putBoolean("seen", seen_delay == 0);
taskExpand.execute(this, args, "messages:expand");
if (seen_delay == 0)
return;
view.postDelayed(new RunnableEx("seen_delay") {
@Override
public void delegate() {
if (values.containsKey("expanded") && values.get("expanded").contains(id)) {
Bundle dargs = new Bundle();
dargs.putLong("id", id);
dargs.putBoolean("seen", true);
taskExpand.execute(FragmentMessages.this, dargs, "messages:seen_delay");
}
}
}, seen_delay);
}
private void handleAutoClose() {
@ -8438,6 +8463,9 @@ public class FragmentMessages extends FragmentBase
return;
}
if (expanded > 0)
values.get("expanded").clear();
handleExit();
FragmentActivity activity = getActivity();

View File

@ -87,6 +87,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
private SwitchCompat swExpandAll;
private SwitchCompat swExpandOne;
private SwitchCompat swAutoClose;
private Spinner spSeenDelay;
private TextView tvAutoSeenHint;
private TextView tvOnClose;
private Spinner spOnClose;
@ -123,6 +124,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
"pull", "pull_all", "autoscroll", "quick_filter", "quick_scroll", "quick_actions", "swipe_sensitivity", "foldernav",
"doubletap", "swipenav", "volumenav", "updown", "reversed", "swipe_close", "swipe_move",
"autoexpand", "expand_first", "expand_all", "expand_one", "collapse_multiple",
"seen_delay",
"autoclose", "onclose", "autoclose_unseen", "autoclose_send", "collapse_marked",
"undo_timeout",
"autoread", "flag_snoozed", "autounflag", "auto_important", "reset_importance",
@ -171,6 +173,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
swExpandAll = view.findViewById(R.id.swExpandAll);
swExpandOne = view.findViewById(R.id.swExpandOne);
swCollapseMultiple = view.findViewById(R.id.swCollapseMultiple);
spSeenDelay = view.findViewById(R.id.spSeenDelay);
tvAutoSeenHint = view.findViewById(R.id.tvAutoSeenHint);
swAutoClose = view.findViewById(R.id.swAutoClose);
tvOnClose = view.findViewById(R.id.tvOnClose);
@ -201,6 +204,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
// Wire controls
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
int[] undoValues = getResources().getIntArray(R.array.undoValues);
ibHelp.setOnClickListener(new View.OnClickListener() {
@Override
@ -442,6 +446,19 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
}
});
spSeenDelay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
int value = undoValues[position];
prefs.edit().putInt("seen_delay", value).apply();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
prefs.edit().remove("seen_delay").apply();
}
});
tvAutoSeenHint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -500,8 +517,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
spUndoTimeout.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
int[] values = getResources().getIntArray(R.array.undoValues);
int value = values[position];
int value = undoValues[position];
prefs.edit().putInt("undo_timeout", value).apply();
}
@ -680,6 +696,8 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
if (view == null || getContext() == null)
return;
int[] undoValues = getResources().getIntArray(R.array.undoValues);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
swRestoreOnLaunch.setChecked(prefs.getBoolean("restore_on_launch", false));
@ -723,6 +741,13 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
swExpandOne.setEnabled(!swExpandAll.isChecked());
swCollapseMultiple.setChecked(prefs.getBoolean("collapse_multiple", true));
int seen_delay = prefs.getInt("seen_delay", 0);
for (int pos = 0; pos < undoValues.length; pos++)
if (undoValues[pos] == seen_delay) {
spSeenDelay.setSelection(pos);
break;
}
swAutoClose.setChecked(prefs.getBoolean("autoclose", true));
String onClose = prefs.getString("onclose", "");
@ -741,7 +766,6 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
swCollapseMarked.setChecked(prefs.getBoolean("collapse_marked", true));
int undo_timeout = prefs.getInt("undo_timeout", 5000);
int[] undoValues = getResources().getIntArray(R.array.undoValues);
for (int pos = 0; pos < undoValues.length; pos++)
if (undoValues[pos] == undo_timeout) {
spUndoTimeout.setSelection(pos);

View File

@ -574,6 +574,28 @@
app:layout_constraintTop_toBottomOf="@id/swExpandOne"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvSeenDelay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="48dp"
android:text="@string/title_advanced_seen_delay"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swCollapseMultiple" />
<Spinner
android:id="@+id/spSeenDelay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:entries="@array/undoNames"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSeenDelay" />
<TextView
android:id="@+id/tvAutoSeenHint"
android:layout_width="0dp"
@ -587,7 +609,7 @@
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swCollapseMultiple" />
app:layout_constraintTop_toBottomOf="@id/spSeenDelay" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swAutoClose"

View File

@ -688,6 +688,7 @@
<string name="title_advanced_expand_all">Automatically expand all read messages</string>
<string name="title_advanced_expand_one">Expand only one message at a time</string>
<string name="title_advanced_collapse_multiple">Collapse messages in a conversation with multiple messages on \'back\'</string>
<string name="title_advanced_seen_delay">Delay automatically marking messages as read</string>
<string name="title_advanced_autoclose">Automatically close conversations</string>
<string name="title_advanced_autoclose_send">Automatically close conversations after sending messages</string>
<string name="title_advanced_onclose">On closing a conversation</string>

View File

@ -8,6 +8,7 @@ Ypupiara
Next version
* Added option to to delay automatically marking messages as read
* Replaced javadns
* Added account/identity option to enforce DNSSEC
* Added account/identity option to enforce DANE, see the FAQ