|
|
- package eu.faircode.email;
-
- /*
- This file is part of Safe email.
-
- Safe email is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- NetGuard is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with NetGuard. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2018 by Marcel Bokhorst (M66B)
- */
-
- import android.Manifest;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.database.Cursor;
- import android.net.Uri;
- import android.os.Bundle;
- import android.provider.ContactsContract;
- import android.provider.OpenableColumns;
- import android.text.Html;
- import android.text.TextUtils;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.Menu;
- import android.view.MenuInflater;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.ViewGroup;
- import android.webkit.MimeTypeMap;
- import android.widget.ArrayAdapter;
- import android.widget.AutoCompleteTextView;
- import android.widget.EditText;
- import android.widget.FilterQueryProvider;
- import android.widget.ImageView;
- import android.widget.ProgressBar;
- import android.widget.Spinner;
- import android.widget.Toast;
-
- import com.google.android.material.bottomnavigation.BottomNavigationView;
- import com.google.android.material.snackbar.Snackbar;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.Date;
- import java.util.List;
-
- import javax.mail.Address;
- import javax.mail.MessageRemovedException;
- import javax.mail.internet.InternetAddress;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.constraintlayout.widget.Group;
- import androidx.core.content.ContextCompat;
- import androidx.cursoradapter.widget.SimpleCursorAdapter;
- import androidx.fragment.app.FragmentTransaction;
- import androidx.lifecycle.Observer;
- import androidx.recyclerview.widget.LinearLayoutManager;
- import androidx.recyclerview.widget.RecyclerView;
-
- import static android.app.Activity.RESULT_OK;
-
- public class FragmentCompose extends FragmentEx {
- private ViewGroup view;
- private Spinner spFrom;
- private ImageView ivIdentityAdd;
- private AutoCompleteTextView etTo;
- private ImageView ivToAdd;
- private AutoCompleteTextView etCc;
- private ImageView ivCcAdd;
- private AutoCompleteTextView etBcc;
- private ImageView ivBccAdd;
- private EditText etSubject;
- private RecyclerView rvAttachment;
- private EditText etBody;
- private BottomNavigationView bottom_navigation;
- private ProgressBar pbWait;
- private Group grpAddresses;
- private Group grpAttachments;
- private Group grpReady;
-
- private AdapterAttachment adapter;
-
- private boolean attaching = false;
- private String action = null;
- private long id = -1; // draft id
- private long account = -1;
- private long reference = -1;
-
- private static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- Log.i(Helper.TAG, "Saving state");
- outState.putString("action", action);
- outState.putLong("id", id);
- outState.putLong("account", account);
- outState.putLong("reference", reference);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- @Nullable
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- // Get arguments
- if (savedInstanceState == null) {
- if (action == null) {
- action = getArguments().getString("action");
- id = getArguments().getLong("id", -1);
- account = getArguments().getLong("account", -1);
- reference = getArguments().getLong("reference", -1);
- }
- } else {
- Log.i(Helper.TAG, "Restoring state");
- action = savedInstanceState.getString("action");
- id = savedInstanceState.getLong("id", -1);
- account = savedInstanceState.getLong("account", -1);
- reference = savedInstanceState.getLong("reference", -1);
- }
-
- setSubtitle(R.string.title_compose);
-
- view = (ViewGroup) inflater.inflate(R.layout.fragment_compose, container, false);
-
- // Get controls
- spFrom = view.findViewById(R.id.spFrom);
- ivIdentityAdd = view.findViewById(R.id.ivIdentityAdd);
- etTo = view.findViewById(R.id.etTo);
- ivToAdd = view.findViewById(R.id.ivToAdd);
- etCc = view.findViewById(R.id.etCc);
- ivCcAdd = view.findViewById(R.id.ivCcAdd);
- etBcc = view.findViewById(R.id.etBcc);
- ivBccAdd = view.findViewById(R.id.ivBccAdd);
- etSubject = view.findViewById(R.id.etSubject);
- rvAttachment = view.findViewById(R.id.rvAttachment);
- etBody = view.findViewById(R.id.etBody);
- bottom_navigation = view.findViewById(R.id.bottom_navigation);
- pbWait = view.findViewById(R.id.pbWait);
- grpAddresses = view.findViewById(R.id.grpAddresses);
- grpAttachments = view.findViewById(R.id.grpAttachments);
- grpReady = view.findViewById(R.id.grpReady);
-
- // Wire controls
-
- ivIdentityAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Bundle args = new Bundle();
- args.putLong("id", -1);
-
- FragmentIdentity fragment = new FragmentIdentity();
- fragment.setArguments(args);
-
- FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
- fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("identity");
- fragmentTransaction.commit();
- }
- });
-
- ivToAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
- startActivityForResult(intent, ActivityCompose.REQUEST_CONTACT_TO);
- }
- });
-
- ivCcAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
- startActivityForResult(intent, ActivityCompose.REQUEST_CONTACT_CC);
- }
- });
-
- ivBccAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
- startActivityForResult(intent, ActivityCompose.REQUEST_CONTACT_BCC);
- }
- });
-
- bottom_navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
- @Override
- public boolean onNavigationItemSelected(@NonNull MenuItem item) {
- onAction(item.getItemId());
-
- return false;
- }
- });
-
- setHasOptionsMenu(true);
-
- // Initialize
- spFrom.setVisibility(View.GONE);
- ivIdentityAdd.setVisibility(View.GONE);
- grpAddresses.setVisibility(View.GONE);
- grpAttachments.setVisibility(View.GONE);
- grpReady.setVisibility(View.GONE);
- pbWait.setVisibility(View.VISIBLE);
- bottom_navigation.getMenu().setGroupEnabled(0, false);
-
- if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CONTACTS)
- == PackageManager.PERMISSION_GRANTED) {
- SimpleCursorAdapter adapter = new SimpleCursorAdapter(
- getContext(),
- android.R.layout.simple_list_item_2,
- null,
- new String[]{
- ContactsContract.Contacts.DISPLAY_NAME,
- ContactsContract.CommonDataKinds.Email.DATA
- },
- new int[]{
- android.R.id.text1,
- android.R.id.text2
- },
- 0);
-
- etTo.setAdapter(adapter);
- etCc.setAdapter(adapter);
- etBcc.setAdapter(adapter);
-
- adapter.setFilterQueryProvider(new FilterQueryProvider() {
- public Cursor runQuery(CharSequence typed) {
- return getContext().getContentResolver().query(
- ContactsContract.CommonDataKinds.Email.CONTENT_URI,
- new String[]{
- ContactsContract.RawContacts._ID,
- ContactsContract.Contacts.DISPLAY_NAME,
- ContactsContract.CommonDataKinds.Email.DATA
- },
- ContactsContract.CommonDataKinds.Email.DATA + " <> ''" +
- " AND (" + ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + typed + "%'" +
- " OR " + ContactsContract.CommonDataKinds.Email.DATA + " LIKE '%" + typed + "%')",
- null,
- "CASE WHEN " + ContactsContract.Contacts.DISPLAY_NAME + " NOT LIKE '%@%' THEN 0 ELSE 1 END" +
- ", " + ContactsContract.Contacts.DISPLAY_NAME +
- ", " + ContactsContract.CommonDataKinds.Email.DATA + " COLLATE NOCASE");
- }
- });
-
- adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
- public CharSequence convertToString(Cursor cursor) {
- int colName = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
- int colEmail = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
- return cursor.getString(colName) + "<" + cursor.getString(colEmail) + ">";
- }
- });
- }
-
- rvAttachment.setHasFixedSize(false);
- LinearLayoutManager llm = new LinearLayoutManager(getContext());
- rvAttachment.setLayoutManager(llm);
-
- adapter = new AdapterAttachment(getContext());
- rvAttachment.setAdapter(adapter);
-
- return view;
- }
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- DB.getInstance(getContext()).identity().liveIdentities(true).observe(getViewLifecycleOwner(), new Observer<List<EntityIdentity>>() {
- @Override
- public void onChanged(@Nullable final List<EntityIdentity> identities) {
- Log.i(Helper.TAG, "Set identities=" + identities.size());
-
- // Sort identities
- Collections.sort(identities, new Comparator<EntityIdentity>() {
- @Override
- public int compare(EntityIdentity i1, EntityIdentity i2) {
- return i1.name.compareTo(i2.name);
- }
- });
-
- // Show identities
- ArrayAdapter<EntityIdentity> adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item, identities);
- adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
- spFrom.setAdapter(adapter);
-
- // Select primary identity
- for (int pos = 0; pos < identities.size(); pos++)
- if (identities.get(pos).primary) {
- spFrom.setSelection(pos);
- break;
- }
-
- spFrom.setVisibility(View.VISIBLE);
- ivIdentityAdd.setVisibility(View.VISIBLE);
-
- // Get draft, might select another identity
- Bundle args = new Bundle();
- args.putString("action", action);
- args.putLong("id", id);
- args.putLong("account", account);
- args.putLong("reference", reference);
- getLoader.load(FragmentCompose.this, ActivityCompose.LOADER_COMPOSE_GET, args);
- }
- });
- }
-
- @Override
- public void onPause() {
- if (!attaching)
- onAction(R.id.action_save);
- super.onPause();
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.menu_compose, menu);
- super.onCreateOptionsMenu(menu, inflater);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.menu_attachment).setEnabled(id >= 0);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_attachment:
- onMenuAttachment();
- return true;
- case R.id.menu_addresses:
- onMenuAddresses();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void onMenuAttachment() {
- attaching = true;
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("*/*");
- startActivityForResult(intent, ActivityCompose.REQUEST_ATTACHMENT);
- }
-
- private void onMenuAddresses() {
- grpAddresses.setVisibility(grpAddresses.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == RESULT_OK) {
- if (requestCode == ActivityCompose.REQUEST_ATTACHMENT) {
- if (data != null)
- handleAddAttachment(data);
- } else
- handlePickContact(requestCode, data);
- }
- }
-
- private void handlePickContact(int requestCode, Intent data) {
- Cursor cursor = null;
- try {
- cursor = getContext().getContentResolver().query(data.getData(),
- new String[]{
- ContactsContract.CommonDataKinds.Email.ADDRESS,
- ContactsContract.Contacts.DISPLAY_NAME
- },
- null, null, null);
- if (cursor != null && cursor.moveToFirst()) {
- int colEmail = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
- int colName = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
- String email = cursor.getString(colEmail);
- String name = cursor.getString(colName);
-
- String text = null;
- if (requestCode == ActivityCompose.REQUEST_CONTACT_TO)
- text = etTo.getText().toString();
- else if (requestCode == ActivityCompose.REQUEST_CONTACT_CC)
- text = etCc.getText().toString();
- else if (requestCode == ActivityCompose.REQUEST_CONTACT_BCC)
- text = etBcc.getText().toString();
-
- InternetAddress address = new InternetAddress(email, name);
- StringBuilder sb = new StringBuilder(text);
- if (sb.length() > 0)
- sb.append(", ");
- sb.append(address.toString());
-
- if (requestCode == ActivityCompose.REQUEST_CONTACT_TO)
- etTo.setText(sb.toString());
- else if (requestCode == ActivityCompose.REQUEST_CONTACT_CC)
- etCc.setText(sb.toString());
- else if (requestCode == ActivityCompose.REQUEST_CONTACT_BCC)
- etBcc.setText(sb.toString());
- }
- } catch (Throwable ex) {
- Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
- Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
- } finally {
- if (cursor != null)
- cursor.close();
- }
- }
-
- private void handleAddAttachment(Intent data) {
- Bundle args = new Bundle();
- args.putLong("id", id);
- args.putParcelable("uri", data.getData());
-
- new SimpleLoader<Void>() {
- @Override
- public Void onLoad(Bundle args) throws IOException {
- Cursor cursor = null;
- try {
- Uri uri = args.getParcelable("uri");
- cursor = getContext().getContentResolver().query(uri, null, null, null, null, null);
- if (cursor == null || !cursor.moveToFirst())
- return null;
-
- DB db = DB.getInstance(getContext());
-
- long id = args.getLong("id");
- EntityMessage draft = db.message().getMessage(id);
-
- EntityAttachment attachment = new EntityAttachment();
- attachment.message = draft.id;
- attachment.sequence = db.attachment().getAttachmentCount(draft.id);
- attachment.name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
-
- String extension = MimeTypeMap.getFileExtensionFromUrl(attachment.name.toLowerCase());
- if (extension != null)
- attachment.type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
- if (extension == null)
- attachment.type = "application/octet-stream";
-
- String size = cursor.getString(cursor.getColumnIndex(OpenableColumns.SIZE));
-
- attachment.size = (size == null ? null : Integer.parseInt(size));
- attachment.progress = 0;
-
- attachment.id = db.attachment().insertAttachment(attachment);
-
- InputStream is = null;
- try {
- is = getContext().getContentResolver().openInputStream(uri);
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- int len;
- byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE];
- while ((len = is.read(buffer)) > 0) {
- os.write(buffer, 0, len);
-
- // Update progress
- if (attachment.size != null) {
- attachment.progress = os.size() * 100 / attachment.size;
- db.attachment().updateAttachment(attachment);
- }
- }
-
- attachment.size = os.size();
- attachment.progress = null;
- attachment.content = os.toByteArray();
- db.attachment().updateAttachment(attachment);
- } finally {
- if (is != null)
- is.close();
- }
-
- return null;
- } finally {
- if (cursor != null)
- cursor.close();
- }
- }
-
- @Override
- public void onLoaded(Bundle args, Void data) {
- attaching = false;
- }
-
- @Override
- public void onException(Bundle args, Throwable ex) {
- Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
- }
- }.load(this, ActivityCompose.LOADER_COMPOSE_ATTACHMENT, args);
- }
-
- private void onAction(int action) {
- bottom_navigation.getMenu().setGroupEnabled(0, false);
-
- EntityIdentity identity = (EntityIdentity) spFrom.getSelectedItem();
-
- Bundle args = new Bundle();
- args.putLong("id", id);
- args.putInt("action", action);
- args.putLong("identity", identity == null ? -1 : identity.id);
- args.putString("to", etTo.getText().toString());
- args.putString("cc", etCc.getText().toString());
- args.putString("bcc", etBcc.getText().toString());
- args.putString("subject", etSubject.getText().toString());
- args.putString("body", etBody.getText().toString());
-
- putLoader.load(this, ActivityCompose.LOADER_COMPOSE_PUT, args);
- }
-
- private SimpleLoader<EntityMessage> getLoader = new SimpleLoader<EntityMessage>() {
- @Override
- public EntityMessage onLoad(Bundle args) {
- String action = args.getString("action");
- long id = args.getLong("id", -1);
- long account = args.getLong("account", -1);
- long reference = args.getLong("reference", -1);
- Log.i(Helper.TAG, "Get load action=" + action + " id=" + id + " account=" + account + " reference=" + reference);
-
- DB db = DB.getInstance(getContext());
-
- EntityMessage draft = db.message().getMessage(id);
- if (draft == null) {
- if ("edit".equals(action))
- throw new IllegalStateException("Message to edit not found");
-
- try {
- db.beginTransaction();
-
- EntityMessage ref = db.message().getMessage(reference);
- if (ref != null)
- account = ref.account;
-
- EntityFolder drafts;
- drafts = db.folder().getFolderByType(account, EntityFolder.DRAFTS);
- if (drafts == null)
- drafts = db.folder().getPrimaryDrafts();
-
- draft = new EntityMessage();
- draft.account = account;
- draft.folder = drafts.id;
-
- if (ref != null) {
- draft.thread = ref.thread;
-
- if ("reply".equals(action)) {
- draft.replying = ref.id;
- draft.to = (ref.reply == null || ref.reply.length == 0 ? ref.from : ref.reply);
- draft.from = ref.to;
-
- } else if ("reply_all".equals(action)) {
- draft.replying = ref.id;
- List<Address> addresses = new ArrayList<>();
- if (draft.reply != null && ref.reply.length > 0)
- addresses.addAll(Arrays.asList(ref.reply));
- else if (draft.from != null)
- addresses.addAll(Arrays.asList(ref.from));
- if (draft.cc != null)
- addresses.addAll(Arrays.asList(ref.cc));
- draft.to = addresses.toArray(new Address[0]);
- draft.from = ref.to;
-
- } else if ("forward".equals(action)) {
- //msg.replying = ref.id;
- draft.from = ref.to;
- }
-
- if ("reply".equals(action) || "reply_all".equals(action)) {
- draft.subject = getContext().getString(R.string.title_subject_reply, ref.subject);
- draft.body = String.format("<br><br>%s %s:<br><br>%s",
- Html.escapeHtml(new Date().toString()),
- Html.escapeHtml(TextUtils.join(", ", draft.to)),
- HtmlHelper.sanitize(getContext(), ref.body, true));
- } else if ("forward".equals(action)) {
- draft.subject = getContext().getString(R.string.title_subject_forward, ref.subject);
- draft.body = String.format("<br><br>%s %s:<br><br>%s",
- Html.escapeHtml(new Date().toString()),
- Html.escapeHtml(TextUtils.join(", ", ref.from)),
- HtmlHelper.sanitize(getContext(), ref.body, true));
- }
- }
-
- if ("new".equals(action))
- draft.body = "";
-
- draft.received = new Date().getTime();
- draft.seen = false;
- draft.ui_seen = false;
- draft.ui_hide = false;
-
- draft.id = db.message().insertMessage(draft);
- draft.msgid = draft.generateMessageId();
- db.message().updateMessage(draft);
- args.putLong("id", draft.id);
-
- EntityOperation.queue(db, draft, EntityOperation.ADD);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(getContext());
- }
-
- return draft;
- }
-
- @Override
- public void onLoaded(Bundle args, EntityMessage draft) {
- id = draft.id;
- if ("new".equals(args.getString("action")))
- action = "edit";
-
- Log.i(Helper.TAG, "Get loaded action=" + action + " id=" + id);
-
- getActivity().invalidateOptionsMenu();
- pbWait.setVisibility(View.GONE);
- grpAddresses.setVisibility("reply_all".equals(action) ? View.VISIBLE : View.GONE);
- grpReady.setVisibility(View.VISIBLE);
-
- ArrayAdapter aa = (ArrayAdapter) spFrom.getAdapter();
- if (aa != null) {
- for (int pos = 0; pos < aa.getCount(); pos++) {
- EntityIdentity identity = (EntityIdentity) aa.getItem(pos);
- if (draft.identity == null
- ? draft.from != null && draft.from.length > 0 && ((InternetAddress) draft.from[0]).getAddress().equals(identity.email)
- : draft.identity.equals(identity.id)) {
- spFrom.setSelection(pos);
- break;
- }
- }
- }
-
- etTo.setText(draft.to == null ? null : TextUtils.join(", ", draft.to));
- etCc.setText(draft.cc == null ? null : TextUtils.join(", ", draft.cc));
- etBcc.setText(draft.bcc == null ? null : TextUtils.join(", ", draft.bcc));
- etSubject.setText(draft.subject);
-
- DB db = DB.getInstance(getContext());
- db.attachment().liveAttachments(draft.id).removeObservers(getViewLifecycleOwner());
- db.attachment().liveAttachments(draft.id).observe(getViewLifecycleOwner(),
- new Observer<List<TupleAttachment>>() {
- @Override
- public void onChanged(@Nullable List<TupleAttachment> attachments) {
- adapter.set(attachments);
- grpAttachments.setVisibility(attachments.size() > 0 ? View.VISIBLE : View.GONE);
- }
- });
-
-
- etBody.setText(TextUtils.isEmpty(draft.body) ? null : Html.fromHtml(draft.body));
-
- if ("edit".equals(action))
- etTo.requestFocus();
- else if ("reply".equals(action) || "reply_all".equals(action))
- etBody.requestFocus();
- else if ("forward".equals(action))
- etTo.requestFocus();
-
- bottom_navigation.getMenu().setGroupEnabled(0, true);
- }
-
- @Override
- public void onException(Bundle args, Throwable ex) {
- Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
- }
- };
-
- private SimpleLoader<EntityMessage> putLoader = new SimpleLoader<EntityMessage>() {
- @Override
- public EntityMessage onLoad(Bundle args) throws Throwable {
- // Get data
- long id = args.getLong("id");
- int action = args.getInt("action");
- long iid = args.getLong("identity");
- String to = args.getString("to");
- String cc = args.getString("cc");
- String bcc = args.getString("bcc");
- String subject = args.getString("subject");
- String body = args.getString("body");
- Log.i(Helper.TAG, "Put load action=" + action + " id=" + id);
-
- // Get draft & selected identity
- DB db = DB.getInstance(getContext());
- EntityMessage draft = db.message().getMessage(id);
- EntityIdentity identity = db.identity().getIdentity(iid);
-
- // Draft deleted by server
- // TODO: better handling of remote deleted message
- if (draft == null)
- throw new MessageRemovedException();
-
- // Convert data
- Address afrom[] = (identity == null ? null : new Address[]{new InternetAddress(identity.email, identity.name)});
- Address ato[] = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to));
- Address acc[] = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc));
- Address abcc[] = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc));
-
- // Update draft
- draft.identity = (identity == null ? null : identity.id);
- draft.from = afrom;
- draft.to = ato;
- draft.cc = acc;
- draft.bcc = abcc;
- draft.subject = subject;
- draft.body = "<pre>" + body.replaceAll("\\r?\\n", "<br />") + "</pre>";
- draft.received = new Date().getTime();
-
- db.message().updateMessage(draft);
-
- // Check data
- try {
- db.beginTransaction();
-
- if (action == R.id.action_trash) {
- draft.ui_hide = true;
- db.message().updateMessage(draft);
-
- EntityFolder trash = db.folder().getFolderByType(draft.account, EntityFolder.TRASH);
- EntityOperation.queue(db, draft, EntityOperation.MOVE, trash.id);
-
- } else if (action == R.id.action_save) {
- String msgid = draft.msgid;
-
- // Save attachments
- List<EntityAttachment> attachments = db.attachment().getAttachments(draft.id);
- for (EntityAttachment attachment : attachments)
- attachment.content = db.attachment().getContent(attachment.id);
-
- // Delete previous draft
- draft.msgid = null;
- draft.ui_hide = true;
- db.message().updateMessage(draft);
-
- EntityOperation.queue(db, draft, EntityOperation.DELETE);
-
- // Create new draft
- draft.id = null;
- draft.uid = null; // unique index folder/uid
- draft.msgid = msgid;
- draft.ui_hide = false;
- draft.id = db.message().insertMessage(draft);
-
- // Restore attachments
- for (EntityAttachment attachment : attachments) {
- attachment.message = draft.id;
- db.attachment().insertAttachment(attachment);
- }
-
- EntityOperation.queue(db, draft, EntityOperation.ADD);
-
- } else if (action == R.id.action_send) {
- // Check data
- if (draft.identity == null)
- throw new IllegalArgumentException(getContext().getString(R.string.title_from_missing));
-
- if (draft.to == null && draft.cc == null && draft.bcc == null)
- throw new IllegalArgumentException(getContext().getString(R.string.title_to_missing));
-
- if (db.attachment().getAttachmentCountWithoutContent(draft.id) > 0)
- throw new IllegalArgumentException(getContext().getString(R.string.title_attachments_missing));
-
- List<EntityAttachment> attachments = db.attachment().getAttachments(draft.id);
- for (EntityAttachment attachment : attachments)
- attachment.content = db.attachment().getContent(attachment.id);
-
- String msgid = draft.msgid;
-
- // Delete draft (cannot move to outbox)
- draft.msgid = null;
- draft.ui_hide = true;
- db.message().updateMessage(draft);
- EntityOperation.queue(db, draft, EntityOperation.DELETE);
-
- // Copy message to outbox
- draft.id = null;
- draft.folder = db.folder().getOutbox().id;
- draft.uid = null;
- draft.msgid = msgid;
- draft.ui_hide = false;
- draft.id = db.message().insertMessage(draft);
-
- for (EntityAttachment attachment : attachments) {
- attachment.message = draft.id;
- db.attachment().insertAttachment(attachment);
- }
-
- EntityOperation.queue(db, draft, EntityOperation.SEND);
- }
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(getContext());
-
- return draft;
- }
-
- @Override
- public void onLoaded(Bundle args, EntityMessage draft) {
- id = draft.id;
- int action = args.getInt("action");
- Log.i(Helper.TAG, "Get loaded action=" + action + " id=" + id);
-
- bottom_navigation.getMenu().setGroupEnabled(0, true);
-
- if (action == R.id.action_trash) {
- getFragmentManager().popBackStack();
- Toast.makeText(getContext(), R.string.title_draft_trashed, Toast.LENGTH_LONG).show();
- } else if (action == R.id.action_save)
- Toast.makeText(getContext(), R.string.title_draft_saved, Toast.LENGTH_LONG).show();
- else if (action == R.id.action_send) {
- getFragmentManager().popBackStack();
- Toast.makeText(getContext(), R.string.title_queued, Toast.LENGTH_LONG).show();
- }
- }
-
- @Override
- public void onException(Bundle args, Throwable ex) {
- bottom_navigation.getMenu().setGroupEnabled(0, true);
-
- if (ex instanceof IllegalArgumentException)
- Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
- else
- Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
- }
- };
- }
|