mirror of https://github.com/M66B/FairEmail.git
Select identify from to address, several fixes and improvements
This commit is contained in:
parent
7052639d48
commit
7b6364b3a2
|
@ -328,6 +328,7 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
draft.id = db.message().insertMessage(draft);
|
||||
|
||||
EntityOperation.queue(ActivityView.this, draft, EntityOperation.ADD);
|
||||
EntityOperation.process(ActivityView.this);
|
||||
|
||||
startActivity(new Intent(ActivityView.this, ActivityCompose.class)
|
||||
.putExtra("id", draft.id));
|
||||
|
|
|
@ -156,6 +156,7 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
|||
db.attachment().setProgress(attachment.id, 0);
|
||||
EntityMessage message = db.message().getMessage(attachment.message);
|
||||
EntityOperation.queue(context, message, EntityOperation.ATTACHMENT, attachment.sequence);
|
||||
EntityOperation.process(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
message.ui_seen = !message.ui_seen;
|
||||
DB.getInstance(context).message().updateMessage(message);
|
||||
EntityOperation.queue(context, message, EntityOperation.SEEN, message.ui_seen);
|
||||
EntityOperation.process(context);
|
||||
}
|
||||
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
|
|
|
@ -93,7 +93,7 @@ public interface DaoMessage {
|
|||
void deleteMessage(long id);
|
||||
|
||||
@Query("DELETE FROM message WHERE folder = :folder AND uid = :uid")
|
||||
void deleteMessage(long folder, long uid);
|
||||
int deleteMessage(long folder, long uid);
|
||||
|
||||
@Query("DELETE FROM message WHERE folder = :folder")
|
||||
void deleteMessages(long folder);
|
||||
|
|
|
@ -31,6 +31,9 @@ import android.util.Log;
|
|||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.arch.persistence.room.ForeignKey.CASCADE;
|
||||
|
||||
@Entity(
|
||||
|
@ -60,6 +63,8 @@ public class EntityOperation {
|
|||
public static final String SEND = "send";
|
||||
public static final String ATTACHMENT = "attachment";
|
||||
|
||||
private static List<Intent> queue = new ArrayList<>();
|
||||
|
||||
static void queue(Context context, EntityMessage message, String name) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
queue(context, message, name, jsonArray);
|
||||
|
@ -92,16 +97,26 @@ public class EntityOperation {
|
|||
operation.args = jsonArray.toString();
|
||||
operation.id = dao.insertOperation(operation);
|
||||
|
||||
synchronized (queue) {
|
||||
queue.add(new Intent(SEND.equals(name)
|
||||
? ServiceSynchronize.ACTION_PROCESS_OUTBOX
|
||||
: ServiceSynchronize.ACTION_PROCESS_FOLDER)
|
||||
.putExtra("folder", message.folder));
|
||||
}
|
||||
|
||||
Log.i(Helper.TAG, "Queued op=" + operation.id + "/" + name +
|
||||
" args=" + operation.args +
|
||||
" msg=" + message.folder + "/" + message.id + " uid=" + message.uid +
|
||||
" purged=" + purged);
|
||||
}
|
||||
|
||||
public static void process(Context context) {
|
||||
// Processing needs to be done after committing to the database
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
lbm.sendBroadcast(
|
||||
new Intent(SEND.equals(name)
|
||||
? ServiceSynchronize.ACTION_PROCESS_OUTBOX
|
||||
: ServiceSynchronize.ACTION_PROCESS_FOLDER)
|
||||
.putExtra("folder", message.folder));
|
||||
synchronized (queue) {
|
||||
for (Intent intent : queue)
|
||||
lbm.sendBroadcast(intent);
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -195,16 +196,18 @@ public class FragmentCompose extends FragmentEx {
|
|||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
spFrom.setAdapter(adapter);
|
||||
|
||||
// Select primary identity, also for saved drafts
|
||||
// Select primary identity
|
||||
for (int pos = 0; pos < identities.size(); pos++)
|
||||
if (identities.get(pos).primary) {
|
||||
spFrom.setSelection(pos);
|
||||
break;
|
||||
}
|
||||
|
||||
// Get might select another identity
|
||||
getLoaderManager().restartLoader(ActivityCompose.LOADER_COMPOSE_GET, getArguments(), getLoaderCallbacks).forceLoad();
|
||||
}
|
||||
});
|
||||
|
||||
getLoaderManager().restartLoader(ActivityCompose.LOADER_COMPOSE_GET, getArguments(), getLoaderCallbacks).forceLoad();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -369,8 +372,16 @@ public class FragmentCompose extends FragmentEx {
|
|||
result.putString("from", msg.to);
|
||||
result.putString("to", to);
|
||||
} else if ("forward".equals(action)) {
|
||||
String to = null;
|
||||
if (msg != null)
|
||||
try {
|
||||
Address[] reply = MessageHelper.decodeAddresses(msg.reply);
|
||||
to = (reply.length == 0 ? msg.from : msg.reply);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
result.putString("from", msg.to);
|
||||
result.putString("to", null);
|
||||
result.putString("to", to);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
|
@ -410,19 +421,23 @@ public class FragmentCompose extends FragmentEx {
|
|||
FragmentCompose.this.rid = rid;
|
||||
|
||||
ArrayAdapter adapter = (ArrayAdapter) spFrom.getAdapter();
|
||||
if (adapter != null)
|
||||
if (adapter != null) {
|
||||
InternetAddress[] afrom = MessageHelper.decodeAddresses(from);
|
||||
for (int pos = 0; pos < adapter.getCount(); pos++) {
|
||||
EntityIdentity identity = (EntityIdentity) adapter.getItem(pos);
|
||||
if (iid < 0 ? identity.primary : iid == identity.id) {
|
||||
if (iid < 0 ? afrom.length > 0 && afrom[0].getAddress().equals(identity.email) : iid == identity.id) {
|
||||
spFrom.setSelection(pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!once) {
|
||||
// Prevent changed fields from being overwritten
|
||||
once = true;
|
||||
|
||||
Handler handler = new Handler();
|
||||
|
||||
etCc.setText(TextUtils.join(", ", MessageHelper.decodeAddresses(cc)));
|
||||
etBcc.setText(TextUtils.join(", ", MessageHelper.decodeAddresses(bcc)));
|
||||
|
||||
|
@ -431,21 +446,34 @@ public class FragmentCompose extends FragmentEx {
|
|||
etSubject.setText(subject);
|
||||
if (body != null)
|
||||
etBody.setText(Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false)));
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
etTo.requestFocus();
|
||||
}
|
||||
});
|
||||
} else if ("reply".equals(action) || "reply_all".equals(action)) {
|
||||
etTo.setText(TextUtils.join(", ", MessageHelper.decodeAddresses(to)));
|
||||
String text = String.format("<br><br>%s %s:<br><br>%s",
|
||||
Html.escapeHtml(new Date().toString()),
|
||||
Html.escapeHtml(TextUtils.join(", ", MessageHelper.decodeAddresses(from))),
|
||||
Html.escapeHtml(TextUtils.join(", ", MessageHelper.decodeAddresses(to))),
|
||||
HtmlHelper.sanitize(getContext(), body, true));
|
||||
etSubject.setText(getContext().getString(R.string.title_subject_reply, subject));
|
||||
etBody.setText(Html.fromHtml(text));
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
etBody.requestFocus();
|
||||
}
|
||||
}, 500);
|
||||
} else if ("forward".equals(action)) {
|
||||
String text = String.format("<br><br>%s %s:<br><br>%s",
|
||||
Html.escapeHtml(new Date().toString()),
|
||||
Html.escapeHtml(TextUtils.join(", ", MessageHelper.decodeAddresses(from))),
|
||||
Html.escapeHtml(TextUtils.join(", ", MessageHelper.decodeAddresses(to))),
|
||||
HtmlHelper.sanitize(getContext(), body, true));
|
||||
etSubject.setText(getContext().getString(R.string.title_subject_forward, subject));
|
||||
etBody.setText(Html.fromHtml(text));
|
||||
etTo.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,37 +555,47 @@ public class FragmentCompose extends FragmentEx {
|
|||
draft.id = message.insertMessage(draft);
|
||||
|
||||
// Check data
|
||||
if ("send".equals(action)) {
|
||||
if (draft.identity == null)
|
||||
throw new MessagingException(getContext().getString(R.string.title_from_missing));
|
||||
if (draft.to == null && draft.cc == null && draft.bcc == null)
|
||||
throw new MessagingException(getContext().getString(R.string.title_to_missing));
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.DELETE);
|
||||
if ("send".equals(action)) {
|
||||
if (draft.identity == null)
|
||||
throw new MessagingException(getContext().getString(R.string.title_from_missing));
|
||||
if (draft.to == null && draft.cc == null && draft.bcc == null)
|
||||
throw new MessagingException(getContext().getString(R.string.title_to_missing));
|
||||
|
||||
draft.id = null;
|
||||
draft.folder = folder.getOutbox().id;
|
||||
draft.ui_hide = false;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.DELETE);
|
||||
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.SEND);
|
||||
|
||||
} else if ("save".equals(action))
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.ADD);
|
||||
|
||||
else if ("trash".equals(action)) {
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.DELETE);
|
||||
|
||||
EntityFolder trash = db.folder().getPrimaryFolder(EntityFolder.TYPE_TRASH);
|
||||
if (trash != null) {
|
||||
draft.id = null;
|
||||
draft.folder = trash.id;
|
||||
draft.folder = folder.getOutbox().id;
|
||||
draft.ui_hide = false;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.SEND);
|
||||
|
||||
} else if ("save".equals(action))
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.ADD);
|
||||
|
||||
else if ("trash".equals(action)) {
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.DELETE);
|
||||
|
||||
EntityFolder trash = db.folder().getPrimaryFolder(EntityFolder.TYPE_TRASH);
|
||||
if (trash != null) {
|
||||
draft.id = null;
|
||||
draft.folder = trash.id;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
|
||||
EntityOperation.queue(getContext(), draft, EntityOperation.ADD);
|
||||
}
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
EntityOperation.process(getContext());
|
||||
|
||||
return null;
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
|
|
|
@ -331,6 +331,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
message.ui_seen = !message.ui_seen;
|
||||
db.message().updateMessage(message);
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.SEEN, message.ui_seen);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -381,6 +382,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
db.message().updateMessage(message);
|
||||
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.DELETE);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -401,6 +403,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
|
||||
EntityFolder trash = db.folder().getFolderByType(message.account, EntityFolder.TYPE_TRASH);
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.MOVE, trash.id);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -427,6 +430,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
|
||||
EntityFolder spam = db.folder().getFolderByType(message.account, EntityFolder.TYPE_JUNK);
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.MOVE, spam.id);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -455,6 +459,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
|
||||
EntityFolder archive = db.folder().getFolderByType(message.account, EntityFolder.TYPE_ARCHIVE);
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.MOVE, archive.id);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -546,6 +551,7 @@ public class FragmentMessage extends FragmentEx {
|
|||
db.message().updateMessage(message);
|
||||
|
||||
EntityOperation.queue(getContext(), message, EntityOperation.MOVE, folder);
|
||||
EntityOperation.process(getContext());
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
|
|
@ -192,9 +192,9 @@ public class MessageHelper {
|
|||
return jaddresses.toString();
|
||||
}
|
||||
|
||||
static Address[] decodeAddresses(String json) {
|
||||
static InternetAddress[] decodeAddresses(String json) {
|
||||
if (json == null)
|
||||
return new Address[0];
|
||||
return new InternetAddress[0];
|
||||
List<Address> result = new ArrayList<>();
|
||||
try {
|
||||
JSONArray jaddresses = new JSONArray(json);
|
||||
|
@ -211,7 +211,7 @@ public class MessageHelper {
|
|||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
return result.toArray(new Address[0]);
|
||||
return result.toArray(new InternetAddress[0]);
|
||||
}
|
||||
|
||||
static String getFormattedAddresses(String json) {
|
||||
|
|
|
@ -242,7 +242,6 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private Notification.Builder getNotification(String action, Throwable ex) {
|
||||
// Build pending intent
|
||||
Intent intent = new Intent(this, ActivityView.class);
|
||||
|
@ -579,8 +578,8 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
try {
|
||||
long uid = ifolder.getUID(imessage);
|
||||
DB db = DB.getInstance(ServiceSynchronize.this);
|
||||
db.message().deleteMessage(folder.id, uid);
|
||||
Log.i(Helper.TAG, "Deleted uid=" + uid);
|
||||
int count = db.message().deleteMessage(folder.id, uid);
|
||||
Log.i(Helper.TAG, "Deleted uid=" + uid + " count=" + count);
|
||||
} catch (MessageRemovedException ex) {
|
||||
Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
@ -694,25 +693,27 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
imessage.setFlag(Flags.Flag.SEEN, jargs.getBoolean(0));
|
||||
|
||||
} else if (EntityOperation.ADD.equals(op.name)) {
|
||||
if (!folder.synchronize) {
|
||||
// Local drafts
|
||||
Log.w(Helper.TAG, "Folder synchronization disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
// Append message
|
||||
EntityMessage msg = message.getMessage(op.message);
|
||||
if (msg == null)
|
||||
return;
|
||||
|
||||
// Disconnect from remote to prevent deletion
|
||||
Long uid = msg.uid;
|
||||
if (msg.uid != null) {
|
||||
msg.uid = null;
|
||||
message.updateMessage(msg);
|
||||
}
|
||||
|
||||
// Execute append
|
||||
Properties props = MessageHelper.getSessionProperties();
|
||||
Session isession = Session.getInstance(props, null);
|
||||
MimeMessage imessage = MessageHelper.from(msg, isession);
|
||||
ifolder.appendMessages(new Message[]{imessage});
|
||||
|
||||
// Drafts can be appended multiple times
|
||||
if (msg.uid != null) {
|
||||
Message previously = ifolder.getMessageByUID(msg.uid);
|
||||
if (uid != null) {
|
||||
Message previously = ifolder.getMessageByUID(uid);
|
||||
if (previously == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
|
@ -972,8 +973,8 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
// Delete local messages not at remote
|
||||
Log.i(Helper.TAG, folder.name + " delete=" + uids.size());
|
||||
for (Long uid : uids) {
|
||||
Log.i(Helper.TAG, folder.name + " delete local uid=" + uid);
|
||||
dao.deleteMessage(folder.id, uid);
|
||||
int count = dao.deleteMessage(folder.id, uid);
|
||||
Log.i(Helper.TAG, folder.name + " delete local uid=" + uid + " count=" + count);
|
||||
}
|
||||
Log.i(Helper.TAG, folder.name + " synced");
|
||||
|
||||
|
|
Loading…
Reference in New Issue