diff --git a/TODO b/TODO index 3a731a9..2b6297e 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,6 @@ Features: - Fingerprints that users can compare to validate - Public address book lookup - "Write email" link in address book -- Add optional CC: and BCC: fields - Attachments - "Empty trash" option in Trash folder - Overlay to explain diff --git a/app/src/main/java/i2p/bote/android/NewEmailFragment.java b/app/src/main/java/i2p/bote/android/NewEmailFragment.java index 109d8f0..0baf19f 100644 --- a/app/src/main/java/i2p/bote/android/NewEmailFragment.java +++ b/app/src/main/java/i2p/bote/android/NewEmailFragment.java @@ -94,9 +94,13 @@ public class NewEmailFragment extends Fragment { Spinner mSpinner; int mDefaultPos; ArrayAdapter mAdapter; - ContactsCompletionView mRecipients; + ImageView mMore; + ContactsCompletionView mTo; + ContactsCompletionView mCc; + ContactsCompletionView mBcc; EditText mSubject; EditText mContent; + boolean mMoreVisible; boolean mDirty; public static NewEmailFragment newInstance(String quoteMsgFolder, String quoteMsgId, @@ -127,7 +131,10 @@ public class NewEmailFragment extends Fragment { super.onViewCreated(view, savedInstanceState); mSpinner = (Spinner) view.findViewById(R.id.sender_spinner); - mRecipients = (ContactsCompletionView) view.findViewById(R.id.recipients); + mMore = (ImageView) view.findViewById(R.id.more); + mTo = (ContactsCompletionView) view.findViewById(R.id.to); + mCc = (ContactsCompletionView) view.findViewById(R.id.cc); + mBcc = (ContactsCompletionView) view.findViewById(R.id.bcc); mSubject = (EditText) view.findViewById(R.id.subject); mContent = (EditText) view.findViewById(R.id.message); @@ -136,7 +143,8 @@ public class NewEmailFragment extends Fragment { QuoteMsgType quoteMsgType = (QuoteMsgType) getArguments().getSerializable(QUOTE_MSG_TYPE); boolean hide = I2PBote.getInstance().getConfiguration().getHideLocale(); - List recipients = new ArrayList(); + List toRecipients = new ArrayList(); + List ccRecipients = new ArrayList(); String origSubject = null; String origContent = null; String origFrom = null; @@ -150,14 +158,15 @@ public class NewEmailFragment extends Fragment { if (quoteMsgType == QuoteMsgType.REPLY) { String recipient = BoteHelper.getNameAndDestination( origEmail.getReplyAddress(I2PBote.getInstance().getIdentities())); - recipients.add(extractPerson(recipient)); + toRecipients.add(extractPerson(recipient)); } else if (quoteMsgType == QuoteMsgType.REPLY_ALL) { + // TODO split between To and Cc // TODO don't include our address // What happens if an email is received by multiple local identities? for (Address address : origEmail.getAllAddresses(true)) { Person person = extractPerson(address.toString()); if (person != null) - recipients.add(person); + toRecipients.add(person); } } @@ -184,6 +193,19 @@ public class NewEmailFragment extends Fragment { mSpinner.setAdapter(identities); mSpinner.setSelection(mDefaultPos); + // Set up Cc/Bcc button + mMore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mCc.setVisibility(mMoreVisible ? View.GONE : View.VISIBLE); + mBcc.setVisibility(mMoreVisible ? View.GONE : View.VISIBLE); + mMore.setImageResource(mMoreVisible ? + R.drawable.ic_unfold_more_grey600_24dp : + R.drawable.ic_unfold_less_grey600_24dp); + mMoreVisible = !mMoreVisible; + } + }); + // Set up contacts auto-complete List contacts = new ArrayList(); try { @@ -227,9 +249,14 @@ public class NewEmailFragment extends Fragment { } }; - mRecipients.setAdapter(mAdapter); - for (Person recipient : recipients) { - mRecipients.addObject(recipient); + mTo.setAdapter(mAdapter); + mCc.setAdapter(mAdapter); + mBcc.setAdapter(mAdapter); + for (Person recipient : toRecipients) { + mTo.addObject(recipient); + } + for (Person recipient : ccRecipients) { + mCc.addObject(recipient); } if (origSubject != null) { @@ -261,7 +288,9 @@ public class NewEmailFragment extends Fragment { } if (savedInstanceState == null) { - mRecipients.setPrefix(getResources().getString(R.string.email_to) + " "); + mTo.setPrefix(getResources().getString(R.string.email_to) + " "); + mCc.setPrefix(getResources().getString(R.string.email_cc) + " "); + mBcc.setPrefix(getResources().getString(R.string.email_bcc) + " "); } TextWatcher dirtyWatcher = new TextWatcher() { @@ -373,21 +402,33 @@ public class NewEmailFragment extends Fragment { // Bote versions to see a sender (and validate the signature). email.setSender(ia); - for (Object obj : mRecipients.getObjects()) { + for (Object obj : mTo.getObjects()) { Person person = (Person) obj; email.addRecipient(Message.RecipientType.TO, new InternetAddress( person.getAddress(), person.getName())); } + if (mMoreVisible) { + for (Object obj : mCc.getObjects()) { + Person person = (Person) obj; + email.addRecipient(Message.RecipientType.CC, new InternetAddress( + person.getAddress(), person.getName())); + } + for (Object obj : mBcc.getObjects()) { + Person person = (Person) obj; + email.addRecipient(Message.RecipientType.BCC, new InternetAddress( + person.getAddress(), person.getName())); + } + } // Check that we have someone to send to Address[] rcpts = email.getAllRecipients(); if (rcpts == null || rcpts.length == 0) { // No recipients - mRecipients.setError(getActivity().getString(R.string.add_one_recipient)); - mRecipients.requestFocus(); + mTo.setError(getActivity().getString(R.string.add_one_recipient)); + mTo.requestFocus(); return false; } else { - mRecipients.setError(null); + mTo.setError(null); } email.setSubject(mSubject.getText().toString(), "UTF-8"); diff --git a/app/src/main/java/i2p/bote/android/ViewEmailFragment.java b/app/src/main/java/i2p/bote/android/ViewEmailFragment.java index e45eed3..8c1b2ad 100644 --- a/app/src/main/java/i2p/bote/android/ViewEmailFragment.java +++ b/app/src/main/java/i2p/bote/android/ViewEmailFragment.java @@ -80,7 +80,7 @@ public class ViewEmailFragment extends Fragment { TextView subject = (TextView) v.findViewById(R.id.email_subject); ImageView picture = (ImageView) v.findViewById(R.id.picture); TextView sender = (TextView) v.findViewById(R.id.email_sender); - LinearLayout recipients = (LinearLayout) v.findViewById(R.id.email_recipients); + LinearLayout toRecipients = (LinearLayout) v.findViewById(R.id.email_to); TextView sent = (TextView) v.findViewById(R.id.email_sent); TextView received = (TextView) v.findViewById(R.id.email_received); TextView content = (TextView) v.findViewById(R.id.email_content); @@ -114,13 +114,37 @@ public class ViewEmailFragment extends Fragment { if (email.isAnonymous() && !BoteHelper.isSentEmail(email)) sender.setTypeface(Typeface.DEFAULT, Typeface.ITALIC); - Address[] emailRecipients = email.getToAddresses(); - if (emailRecipients != null) { - for (Address recipient : emailRecipients) { + Address[] emailToRecipients = email.getToAddresses(); + if (emailToRecipients != null) { + for (Address recipient : emailToRecipients) { TextView tv = new TextView(getActivity()); tv.setText(BoteHelper.getDisplayAddress(recipient.toString())); tv.setTextAppearance(getActivity(), R.style.TextAppearance_AppCompat_Secondary); - recipients.addView(tv); + toRecipients.addView(tv); + } + } + + Address[] emailCcRecipients = email.getCCAddresses(); + if (emailCcRecipients != null) { + v.findViewById(R.id.email_cc_row).setVisibility(View.VISIBLE); + LinearLayout ccRecipients = (LinearLayout) v.findViewById(R.id.email_cc); + for (Address recipient : emailCcRecipients) { + TextView tv = new TextView(getActivity()); + tv.setText(BoteHelper.getDisplayAddress(recipient.toString())); + tv.setTextAppearance(getActivity(), R.style.TextAppearance_AppCompat_Secondary); + ccRecipients.addView(tv); + } + } + + Address[] emailBccRecipients = email.getBCCAddresses(); + if (emailBccRecipients != null) { + v.findViewById(R.id.email_bcc_row).setVisibility(View.VISIBLE); + LinearLayout bccRecipients = (LinearLayout) v.findViewById(R.id.email_bcc); + for (Address recipient : emailBccRecipients) { + TextView tv = new TextView(getActivity()); + tv.setText(BoteHelper.getDisplayAddress(recipient.toString())); + tv.setTextAppearance(getActivity(), R.style.TextAppearance_AppCompat_Secondary); + bccRecipients.addView(tv); } } diff --git a/app/src/main/res/drawable-hdpi/ic_unfold_less_grey600_24dp.png b/app/src/main/res/drawable-hdpi/ic_unfold_less_grey600_24dp.png new file mode 100644 index 0000000..e1fb473 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_unfold_less_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_unfold_more_grey600_24dp.png b/app/src/main/res/drawable-hdpi/ic_unfold_more_grey600_24dp.png new file mode 100644 index 0000000..3c9a6f3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_unfold_more_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_unfold_less_grey600_24dp.png b/app/src/main/res/drawable-mdpi/ic_unfold_less_grey600_24dp.png new file mode 100644 index 0000000..99a474a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_unfold_less_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_unfold_more_grey600_24dp.png b/app/src/main/res/drawable-mdpi/ic_unfold_more_grey600_24dp.png new file mode 100644 index 0000000..cbcda9d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_unfold_more_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_unfold_less_grey600_24dp.png b/app/src/main/res/drawable-xhdpi/ic_unfold_less_grey600_24dp.png new file mode 100644 index 0000000..bc3e363 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_unfold_less_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_unfold_more_grey600_24dp.png b/app/src/main/res/drawable-xhdpi/ic_unfold_more_grey600_24dp.png new file mode 100644 index 0000000..bd15f86 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_unfold_more_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_unfold_less_grey600_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_unfold_less_grey600_24dp.png new file mode 100644 index 0000000..f43a8b8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_unfold_less_grey600_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_unfold_more_grey600_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_unfold_more_grey600_24dp.png new file mode 100644 index 0000000..17618be Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_unfold_more_grey600_24dp.png differ diff --git a/app/src/main/res/layout/fragment_new_email.xml b/app/src/main/res/layout/fragment_new_email.xml index 5586118..506ad11 100644 --- a/app/src/main/res/layout/fragment_new_email.xml +++ b/app/src/main/res/layout/fragment_new_email.xml @@ -1,29 +1,57 @@ - + android:paddingTop="@dimen/activity_vertical_margin"> + android:orientation="vertical"> + android:layout_height="wrap_content"/> + + + + + + + + + + + android:layout_height="wrap_content" + android:visibility="gone"/> - - + + android:inputType="textEmailSubject"/> + android:inputType="textMultiLine"/> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_email.xml b/app/src/main/res/layout/fragment_view_email.xml index af3ff25..6205564 100644 --- a/app/src/main/res/layout/fragment_view_email.xml +++ b/app/src/main/res/layout/fragment_view_email.xml @@ -93,7 +93,51 @@ android:textAppearance="@style/TextAppearance.AppCompat.Secondary"/> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b0c64b5..0b99b47 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,6 +103,8 @@ This email does not have a valid signature. It was probably not sent by %s. From: To: + Cc: + Bcc: Sent: Received: Status: