diff --git a/FAQ.md b/FAQ.md index ea6b986d01..ddcb1eeedd 100644 --- a/FAQ.md +++ b/FAQ.md @@ -980,13 +980,15 @@ but even Google's Chrome cannot handle this. **(61) Why are some messages shown dimmed?** Messages shown dimmed are locally moved messages for which the move is not confirmed by the server yet. -This can happen when there is no connection with the server or when the messages are too old to be synchronized. +This can happen when the folder is set to not synchronize, when there is no connection to the server or when the messages are too old to be synchronized. Eventually, these messages will be synchronized when the connection to the server is restored or will be deleted if they are too old to be synchronized. -Some providers don't store sent messages, in this case messages in the sent folder might never be synchronized. - You can view these messages, but you cannot move these messages again until the previous move has been confirmed by the server. +Some providers don't keep track of sent messages or you might be using an SMTP server not related to the provider. +This will result in messages in the sent folder never to be synchronized. +In these cases you should enable the advanced identity setting *Store sent messages*. +
diff --git a/app/src/main/java/eu/faircode/email/EntityIdentity.java b/app/src/main/java/eu/faircode/email/EntityIdentity.java index a75479c40b..19d82c16d7 100644 --- a/app/src/main/java/eu/faircode/email/EntityIdentity.java +++ b/app/src/main/java/eu/faircode/email/EntityIdentity.java @@ -76,9 +76,9 @@ public class EntityIdentity { public String replyto; public String bcc; @NonNull - public Boolean delivery_receipt; + public Boolean delivery_receipt = false; @NonNull - public Boolean read_receipt; + public Boolean read_receipt = false; @NonNull public Boolean store_sent = false; // obsolete public Long sent_folder; // obsolete @@ -109,6 +109,7 @@ public class EntityIdentity { json.put("bcc", bcc); json.put("delivery_receipt", delivery_receipt); json.put("read_receipt", read_receipt); + json.put("store_sent", store_sent); // not state // not error return json; @@ -146,13 +147,12 @@ public class EntityIdentity { if (json.has("delivery_receipt")) identity.delivery_receipt = json.getBoolean("delivery_receipt"); - else - identity.delivery_receipt = false; if (json.has("read_receipt")) identity.read_receipt = json.getBoolean("read_receipt"); - else - identity.read_receipt = false; + + if (json.has("store_sent")) + identity.store_sent = json.getBoolean("store_sent"); return identity; } diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index 2a513c0c00..af6d249c2a 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -166,13 +166,17 @@ public class EntityOperation { db.message().countMessageByMsgId(target.id, message.msgid) == 0) { long id = message.id; long uid = message.uid; + boolean browsed = message.ui_browsed; message.id = null; message.uid = null; message.folder = target.id; + message.ui_browsed = true; long newid = db.message().insertMessage(message); message.id = id; message.uid = uid; message.folder = source.id; + message.ui_browsed = browsed; + if (message.content) try { Helper.copy( diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index 44a8bce3f8..6072409bb2 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -111,6 +111,8 @@ public class FragmentIdentity extends FragmentBase { private CheckBox cbDeliveryReceipt; private CheckBox cbReadReceipt; + private CheckBox cbStoreSent; + private Button btnSave; private ContentLoadingProgressBar pbSave; private TextView tvError; @@ -174,6 +176,8 @@ public class FragmentIdentity extends FragmentBase { cbDeliveryReceipt = view.findViewById(R.id.cbDeliveryReceipt); cbReadReceipt = view.findViewById(R.id.cbReadReceipt); + cbStoreSent = view.findViewById(R.id.cbStoreSent); + btnSave = view.findViewById(R.id.btnSave); pbSave = view.findViewById(R.id.pbSave); tvError = view.findViewById(R.id.tvError); @@ -479,6 +483,7 @@ public class FragmentIdentity extends FragmentBase { args.putString("bcc", etBcc.getText().toString().trim()); args.putBoolean("delivery_receipt", cbDeliveryReceipt.isChecked()); args.putBoolean("read_receipt", cbReadReceipt.isChecked()); + args.putBoolean("store_sent", cbStoreSent.isChecked()); args.putLong("account", account == null ? -1 : account.id); args.putInt("auth_type", account == null || account.auth_type == null ? Helper.AUTH_TYPE_PASSWORD : account.auth_type); args.putString("host", etHost.getText().toString()); @@ -535,6 +540,8 @@ public class FragmentIdentity extends FragmentBase { String bcc = args.getString("bcc"); boolean delivery_receipt = args.getBoolean("delivery_receipt"); boolean read_receipt = args.getBoolean("read_receipt"); + boolean store_sent = args.getBoolean("store_sent"); + if (TextUtils.isEmpty(name)) throw new IllegalArgumentException(context.getString(R.string.title_no_name)); @@ -633,7 +640,7 @@ public class FragmentIdentity extends FragmentBase { identity.bcc = bcc; identity.delivery_receipt = delivery_receipt; identity.read_receipt = read_receipt; - identity.store_sent = false; + identity.store_sent = store_sent; identity.sent_folder = null; identity.error = null; @@ -727,6 +734,7 @@ public class FragmentIdentity extends FragmentBase { etBcc.setText(identity == null ? null : identity.bcc); cbDeliveryReceipt.setChecked(identity == null ? false : identity.delivery_receipt); cbReadReceipt.setChecked(identity == null ? false : identity.read_receipt); + cbStoreSent.setChecked(identity == null ? false : identity.store_sent); color = (identity == null || identity.color == null ? Color.TRANSPARENT : identity.color); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 808315f704..8c0405abf7 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -1311,9 +1311,13 @@ public class FragmentMessages extends FragmentBase { db.account().livePrimaryAccount().observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(EntityAccount account) { - primary = (account == null ? -1 : account.id); - connected = (account != null && "connected".equals(account.state)); - getActivity().invalidateOptionsMenu(); + long primary = (account == null ? -1 : account.id); + boolean connected = (account != null && "connected".equals(account.state)); + if (FragmentMessages.this.primary != primary || FragmentMessages.this.connected != connected) { + FragmentMessages.this.primary = primary; + FragmentMessages.this.connected = connected; + getActivity().invalidateOptionsMenu(); + } } }); @@ -1360,8 +1364,11 @@ public class FragmentMessages extends FragmentBase { else setSubtitle(name); - outbox = EntityFolder.OUTBOX.equals(folder.type); - getActivity().invalidateOptionsMenu(); + boolean outbox = EntityFolder.OUTBOX.equals(folder.type); + if (FragmentMessages.this.outbox != outbox) { + FragmentMessages.this.outbox = outbox; + getActivity().invalidateOptionsMenu(); + } } swipeRefresh.setRefreshing( @@ -1584,8 +1591,6 @@ public class FragmentMessages extends FragmentBase { (viewType == AdapterMessage.ViewType.UNIFIED || viewType == AdapterMessage.ViewType.FOLDER)); menu.findItem(R.id.menu_snoozed).setChecked(prefs.getBoolean("snoozed", false)); - menu.findItem(R.id.menu_move_sent).setVisible(!selection && outbox); - super.onPrepareOptionsMenu(menu); } @@ -1629,10 +1634,6 @@ public class FragmentMessages extends FragmentBase { onMenuSnoozed(); return true; - case R.id.menu_move_sent: - onMenuMoveSent(); - return true; - default: return super.onOptionsItemSelected(item); } @@ -1688,47 +1689,6 @@ public class FragmentMessages extends FragmentBase { loadMessages(); } - private void onMenuMoveSent() { - Bundle args = new Bundle(); - args.putLong("folder", folder); - - new SimpleTask() { - @Override - protected Void onExecute(Context context, Bundle args) { - long outbox = args.getLong("folder"); - - DB db = DB.getInstance(context); - try { - db.beginTransaction(); - - for (EntityMessage message : db.message().getMessageSeen(outbox)) - if (message.identity != null) { - EntityIdentity identity = db.identity().getIdentity(message.identity); - EntityFolder sent = db.folder().getFolderByType(identity.account, EntityFolder.SENT); - if (sent != null) { - message.folder = sent.id; - message.uid = null; - db.message().updateMessage(message); - Log.i("Appending sent msgid=" + message.msgid); - EntityOperation.queue(context, db, message, EntityOperation.ADD); // Could already exist - } - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - return null; - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex); - } - }.execute(this, args, "messages:movesent"); - } - private void loadMessages() { ViewModelBrowse modelBrowse = ViewModelProviders.of(getActivity()).get(ViewModelBrowse.class); modelBrowse.set(getContext(), folder, search, REMOTE_PAGE_SIZE); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 45ca6a5492..5d9e62f86d 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -1840,6 +1840,12 @@ public class ServiceSynchronize extends LifecycleService { db.message().setMessageSent(sid, imessage.getSentDate().getTime()); db.message().setMessageUiHide(sid, false); db.message().deleteMessage(message.id); + + if (ident.store_sent) { + message.id = sid; + message.folder = sent.id; + EntityOperation.queue(this, db, message, EntityOperation.ADD); + } } db.setTransactionSuccessful(); @@ -2560,6 +2566,12 @@ public class ServiceSynchronize extends LifecycleService { Log.i(folder.name + " updated id=" + message.id + " uid=" + message.uid + " unhide"); } + if (message.ui_browsed) { + update = true; + message.ui_browsed = false; + Log.i(folder.name + " updated id=" + message.id + " uid=" + message.uid + " unbrowse"); + } + if (update) db.message().updateMessage(message); } diff --git a/app/src/main/res/layout/fragment_identity.xml b/app/src/main/res/layout/fragment_identity.xml index 844be84fed..4de55f03ff 100644 --- a/app/src/main/res/layout/fragment_identity.xml +++ b/app/src/main/res/layout/fragment_identity.xml @@ -477,13 +477,31 @@ android:id="@+id/tvReceipt" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="12dp" android:text="@string/title_identity_receipt_remark" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="italic" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/cbReadReceipt" /> + + + +