diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java
index 3b74321436..678215c52d 100644
--- a/app/src/main/java/eu/faircode/email/Core.java
+++ b/app/src/main/java/eu/faircode/email/Core.java
@@ -3758,6 +3758,8 @@ class Core {
// Local address contains control or whitespace in string ``mailing list someone@example.org''
message.deliveredto = helper.getDeliveredTo();
message.thread = helper.getThreadId(context, account.id, folder.id, uid);
+ if (BuildConfig.DEBUG && message.thread.startsWith("outlook:"))
+ message.warning = message.thread;
message.priority = helper.getPriority();
for (String keyword : keywords)
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java
index 4a4e5838ec..a62fcb6086 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java
@@ -81,6 +81,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
private SwitchCompat swDeleteUnseen;
private SwitchCompat swSyncKept;
private SwitchCompat swGmailThread;
+ private SwitchCompat swOutlookThread;
private SwitchCompat swSubjectThreading;
private TextView tvSubjectThreading;
private SwitchCompat swSyncFolders;
@@ -107,7 +108,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
"enabled", "poll_interval", "auto_optimize", "schedule", "schedule_start", "schedule_end",
"sync_quick_imap", "sync_quick_pop",
"sync_nodate", "sync_unseen", "sync_flagged", "delete_unseen", "sync_kept",
- "gmail_thread_id", "subject_threading",
+ "gmail_thread_id", "outlook_thread_id", "subject_threading",
"sync_folders", "sync_folders_poll", "sync_shared_folders", "subscriptions",
"check_authentication", "check_tls", "check_reply_domain", "check_mx", "check_blocklist", "use_blocklist",
"tune_keep_alive"
@@ -153,6 +154,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
swDeleteUnseen = view.findViewById(R.id.swDeleteUnseen);
swSyncKept = view.findViewById(R.id.swSyncKept);
swGmailThread = view.findViewById(R.id.swGmailThread);
+ swOutlookThread = view.findViewById(R.id.swOutlookThread);
swSubjectThreading = view.findViewById(R.id.swSubjectThreading);
tvSubjectThreading = view.findViewById(R.id.tvSubjectThreading);
swSyncFolders = view.findViewById(R.id.swSyncFolders);
@@ -333,7 +335,15 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("gmail_thread_id", checked).apply();
- swSubjectThreading.setEnabled(!checked);
+ swSubjectThreading.setEnabled(!swGmailThread.isChecked() && !swOutlookThread.isChecked());
+ }
+ });
+
+ swOutlookThread.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("outlook_thread_id", checked).apply();
+ swSubjectThreading.setEnabled(!swGmailThread.isChecked() && !swOutlookThread.isChecked());
}
});
@@ -442,6 +452,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
// Initialize
FragmentDialogTheme.setBackground(getContext(), view, false);
+ swOutlookThread.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE);
tvSubjectThreading.setText(getString(R.string.title_advanced_subject_threading_hint, MessageHelper.MAX_SUBJECT_AGE));
DB db = DB.getInstance(getContext());
@@ -526,8 +537,9 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
swDeleteUnseen.setChecked(prefs.getBoolean("delete_unseen", false));
swSyncKept.setChecked(prefs.getBoolean("sync_kept", true));
swGmailThread.setChecked(prefs.getBoolean("gmail_thread_id", false));
+ swOutlookThread.setChecked(prefs.getBoolean("outlook_thread_id", false));
swSubjectThreading.setChecked(prefs.getBoolean("subject_threading", false));
- swSubjectThreading.setEnabled(!swGmailThread.isChecked());
+ swSubjectThreading.setEnabled(!swGmailThread.isChecked() && !swOutlookThread.isChecked());
swSyncFolders.setChecked(prefs.getBoolean("sync_folders", true));
swSyncFoldersPoll.setChecked(prefs.getBoolean("sync_folders_poll", false));
swSyncFoldersPoll.setEnabled(swSyncFolders.isChecked());
diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java
index 269eaf5bbc..277a7785ed 100644
--- a/app/src/main/java/eu/faircode/email/MessageHelper.java
+++ b/app/src/main/java/eu/faircode/email/MessageHelper.java
@@ -26,6 +26,7 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.system.ErrnoException;
import android.text.TextUtils;
+import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -86,6 +87,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.TimeZone;
+import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1390,11 +1392,35 @@ public class MessageHelper {
boolean gmail_thread_id = prefs.getBoolean("gmail_thread_id", false);
if (gmail_thread_id) {
long thrid = ((GmailMessage) imessage).getThrId();
+ Log.i("Gmail thread=" + thrid);
if (thrid > 0)
return "gmail:" + thrid;
}
}
+ // https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxomsg/9e994fbb-b839-495f-84e3-2c8c02c7dd9b
+ String tindex = imessage.getHeader("Thread-Index", null);
+ try {
+ if (tindex != null) {
+ boolean outlook_thread_id = prefs.getBoolean("outlook_thread_id", false);
+ if (outlook_thread_id) {
+ byte[] data = Base64.decode(tindex, Base64.DEFAULT);
+ if (data.length >= 22) {
+ long msb = 0, lsb = 0;
+ for (int i = 0 + 6; i < 8 + 6; i++)
+ msb = (msb << 8) | (data[i] & 0xff);
+ for (int i = 8 + 6; i < 16 + 6; i++)
+ lsb = (lsb << 8) | (data[i] & 0xff);
+ UUID guid = new UUID(msb, lsb);
+ Log.i("Outlook thread=" + guid);
+ return "outlook:" + guid;
+ }
+ }
+ }
+ } catch (Throwable ex) {
+ Log.w(ex);
+ }
+
String thread = null;
String msgid = getMessageID();
diff --git a/app/src/main/res/layout/fragment_options_synchronize.xml b/app/src/main/res/layout/fragment_options_synchronize.xml
index b2962cc490..b80bdbf83d 100644
--- a/app/src/main/res/layout/fragment_options_synchronize.xml
+++ b/app/src/main/res/layout/fragment_options_synchronize.xml
@@ -577,6 +577,29 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swGmailThread" />
+
+
+
+
Delete old unread messages
Check if old messages were removed from the server
Gmail message grouping style for Gmail accounts
+ Use Outlook thread index
Group messages by sender and subject
Synchronize folder list
Actively synchronize folder list