Removed message action bar

pull/175/head
M66B 5 years ago
parent 3b700ba73c
commit b58e4bca85

@ -127,8 +127,6 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.github.chrisbanes.photoview.PhotoView; import com.github.chrisbanes.photoview.PhotoView;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomnavigation.LabelVisibilityMode;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
@ -231,7 +229,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private boolean authentication; private boolean authentication;
private static boolean debug; private static boolean debug;
private int answers = -1;
private boolean gotoTop = false; private boolean gotoTop = false;
private boolean firstClick = false; private boolean firstClick = false;
private int searchResult = 0; private int searchResult = 0;
@ -295,8 +292,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
View.OnClickListener, View.OnClickListener,
View.OnLongClickListener, View.OnLongClickListener,
View.OnTouchListener, View.OnTouchListener,
View.OnLayoutChangeListener, View.OnLayoutChangeListener {
BottomNavigationView.OnNavigationItemSelectedListener {
private ViewCardOptional card; private ViewCardOptional card;
private View view; private View view;
private View header; private View header;
@ -379,15 +375,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private Button btnDownloadAttachments; private Button btnDownloadAttachments;
private TextView tvNoInternetAttachments; private TextView tvNoInternetAttachments;
private BottomNavigationView bnvActions; private View vSeparator;
private Group grpActions;
private ImageButton ibFull; private ImageButton ibFull;
private ImageButton ibImages; private ImageButton ibImages;
private ImageButton ibUnsubscribe; private ImageButton ibUnsubscribe;
private ImageButton ibJunk; private ImageButton ibJunk;
private ImageButton ibVerify;
private ImageButton ibDecrypt; private ImageButton ibDecrypt;
private ImageButton ibVerify;
private ImageButton ibUndo;
private ImageButton ibMore;
private TextView tvSignedData; private TextView tvSignedData;
private TextView tvBody; private TextView tvBody;
@ -565,21 +561,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
btnDownloadAttachments = attachments.findViewById(R.id.btnDownloadAttachments); btnDownloadAttachments = attachments.findViewById(R.id.btnDownloadAttachments);
tvNoInternetAttachments = attachments.findViewById(R.id.tvNoInternetAttachments); tvNoInternetAttachments = attachments.findViewById(R.id.tvNoInternetAttachments);
bnvActions = vsBody.findViewById(R.id.bnvActions); vSeparator = vsBody.findViewById(R.id.vSeparator);
if (compact) {
bnvActions.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_UNLABELED);
ViewGroup.LayoutParams lparam = bnvActions.getLayoutParams();
lparam.height = dp36;
bnvActions.setLayoutParams(lparam);
}
grpActions = vsBody.findViewById(R.id.grpActions);
ibFull = vsBody.findViewById(R.id.ibFull); ibFull = vsBody.findViewById(R.id.ibFull);
ibImages = vsBody.findViewById(R.id.ibImages); ibImages = vsBody.findViewById(R.id.ibImages);
ibUnsubscribe = vsBody.findViewById(R.id.ibUnsubscribe); ibUnsubscribe = vsBody.findViewById(R.id.ibUnsubscribe);
ibJunk = vsBody.findViewById(R.id.ibJunk); ibJunk = vsBody.findViewById(R.id.ibJunk);
ibVerify = vsBody.findViewById(R.id.ibVerify);
ibDecrypt = vsBody.findViewById(R.id.ibDecrypt); ibDecrypt = vsBody.findViewById(R.id.ibDecrypt);
ibVerify = vsBody.findViewById(R.id.ibVerify);
ibUndo = vsBody.findViewById(R.id.ibUndo);
ibMore = vsBody.findViewById(R.id.ibMore);
tvSignedData = vsBody.findViewById(R.id.tvSignedData); tvSignedData = vsBody.findViewById(R.id.tvSignedData);
tvBody = vsBody.findViewById(R.id.tvBody); tvBody = vsBody.findViewById(R.id.tvBody);
@ -650,14 +640,14 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
btnSaveAttachments.setOnClickListener(this); btnSaveAttachments.setOnClickListener(this);
btnDownloadAttachments.setOnClickListener(this); btnDownloadAttachments.setOnClickListener(this);
bnvActions.setOnNavigationItemSelectedListener(this);
ibFull.setOnClickListener(this); ibFull.setOnClickListener(this);
ibImages.setOnClickListener(this); ibImages.setOnClickListener(this);
ibUnsubscribe.setOnClickListener(this); ibUnsubscribe.setOnClickListener(this);
ibJunk.setOnClickListener(this); ibJunk.setOnClickListener(this);
ibVerify.setOnClickListener(this);
ibDecrypt.setOnClickListener(this); ibDecrypt.setOnClickListener(this);
ibVerify.setOnClickListener(this);
ibUndo.setOnClickListener(this);
ibMore.setOnClickListener(this);
ibDownloading.setOnClickListener(this); ibDownloading.setOnClickListener(this);
@ -718,14 +708,14 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
btnSaveAttachments.setOnClickListener(null); btnSaveAttachments.setOnClickListener(null);
btnDownloadAttachments.setOnClickListener(null); btnDownloadAttachments.setOnClickListener(null);
bnvActions.setOnNavigationItemSelectedListener(null);
ibFull.setOnClickListener(null); ibFull.setOnClickListener(null);
ibImages.setOnClickListener(null); ibImages.setOnClickListener(null);
ibUnsubscribe.setOnClickListener(null); ibUnsubscribe.setOnClickListener(null);
ibJunk.setOnClickListener(null); ibJunk.setOnClickListener(null);
ibVerify.setOnClickListener(null);
ibDecrypt.setOnClickListener(null); ibDecrypt.setOnClickListener(null);
ibVerify.setOnClickListener(null);
ibUndo.setOnClickListener(null);
ibMore.setOnClickListener(null);
ibDownloading.setOnClickListener(null); ibDownloading.setOnClickListener(null);
@ -1144,15 +1134,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
btnDownloadAttachments.setVisibility(View.GONE); btnDownloadAttachments.setVisibility(View.GONE);
tvNoInternetAttachments.setVisibility(View.GONE); tvNoInternetAttachments.setVisibility(View.GONE);
bnvActions.setVisibility(View.GONE); vSeparator.setVisibility(View.GONE);
grpActions.setVisibility(View.GONE);
ibFull.setVisibility(View.GONE); ibFull.setVisibility(View.GONE);
ibImages.setVisibility(View.GONE); ibImages.setVisibility(View.GONE);
ibUnsubscribe.setVisibility(View.GONE); ibUnsubscribe.setVisibility(View.GONE);
ibJunk.setVisibility(View.GONE); ibJunk.setVisibility(View.GONE);
ibVerify.setVisibility(View.GONE);
ibDecrypt.setVisibility(View.GONE); ibDecrypt.setVisibility(View.GONE);
ibVerify.setVisibility(View.GONE);
ibUndo.setVisibility(View.GONE);
ibMore.setVisibility(View.GONE);
tvSignedData.setVisibility(View.GONE); tvSignedData.setVisibility(View.GONE);
tvBody.setVisibility(View.GONE); tvBody.setVisibility(View.GONE);
@ -1296,18 +1286,17 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
tvNoInternetHeaders.setVisibility(View.GONE); tvNoInternetHeaders.setVisibility(View.GONE);
} }
grpActions.setVisibility(View.VISIBLE); vSeparator.setVisibility(View.VISIBLE);
for (int i = 0; i < bnvActions.getMenu().size(); i++)
bnvActions.getMenu().getItem(i).setVisible(false);
ibFull.setEnabled(false); ibFull.setEnabled(false);
ibFull.setVisibility(View.VISIBLE); ibFull.setVisibility(View.VISIBLE);
ibImages.setVisibility(View.GONE); ibImages.setVisibility(View.GONE);
ibUnsubscribe.setVisibility(View.GONE); ibUnsubscribe.setVisibility(View.GONE);
ibJunk.setEnabled(false); ibJunk.setEnabled(false);
ibJunk.setVisibility(View.GONE); ibJunk.setVisibility(View.GONE);
ibVerify.setVisibility(View.GONE);
ibDecrypt.setVisibility(View.GONE); ibDecrypt.setVisibility(View.GONE);
ibVerify.setVisibility(View.GONE);
ibUndo.setVisibility(EntityFolder.OUTBOX.equals(message.folderType) ? View.VISIBLE : View.GONE);
ibMore.setVisibility(EntityFolder.OUTBOX.equals(message.folderType) ? View.GONE : View.VISIBLE);
tvSignedData.setVisibility(View.GONE); tvSignedData.setVisibility(View.GONE);
// Addresses // Addresses
@ -1442,39 +1431,11 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
boolean inOutbox = EntityFolder.OUTBOX.equals(message.folderType); boolean inOutbox = EntityFolder.OUTBOX.equals(message.folderType);
boolean inArchive = EntityFolder.ARCHIVE.equals(message.folderType);
boolean inTrash = EntityFolder.TRASH.equals(message.folderType); boolean inTrash = EntityFolder.TRASH.equals(message.folderType);
boolean inJunk = EntityFolder.JUNK.equals(message.folderType);
delete = (inTrash || !hasTrash || inOutbox); delete = (inTrash || !hasTrash || inOutbox);
ibJunk.setEnabled(hasJunk); ibJunk.setEnabled(hasJunk);
bnvActions.getMenu().findItem(R.id.action_more).setVisible(!inOutbox);
if (!message.folderReadOnly) {
bnvActions.getMenu().findItem(R.id.action_delete).setVisible(
(delete ? message.uid != null || !TextUtils.isEmpty(message.msgid) : message.uid != null));
bnvActions.getMenu().findItem(R.id.action_delete).setTitle(
delete ? R.string.title_delete : R.string.title_trash);
bnvActions.getMenu().findItem(R.id.action_move).setVisible(
message.uid != null || inOutbox);
bnvActions.getMenu().findItem(R.id.action_move).setTitle(
inOutbox ? R.string.title_folder_drafts : R.string.title_move);
bnvActions.getMenu().findItem(R.id.action_move).setIcon(
inOutbox ? R.drawable.baseline_drafts_24 : R.drawable.baseline_folder_24);
bnvActions.getMenu().findItem(R.id.action_archive).setVisible(
message.uid != null && (inJunk || (!inArchive && hasArchive)));
bnvActions.getMenu().findItem(R.id.action_archive).setTitle(
inJunk ? R.string.title_folder_inbox : R.string.title_archive);
bnvActions.getMenu().findItem(R.id.action_archive).setIcon(
inJunk ? R.drawable.baseline_inbox_24 : R.drawable.baseline_archive_24);
}
bnvActions.getMenu().findItem(R.id.action_reply).setEnabled(message.content);
bnvActions.getMenu().findItem(R.id.action_reply).setVisible(!inOutbox);
} }
@Override @Override
@ -2356,9 +2317,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.ibJunk: case R.id.ibJunk:
onActionJunk(message); onActionJunk(message);
break; break;
case R.id.ibVerify:
onActionDecrypt(message, false);
break;
case R.id.ibDecrypt: case R.id.ibDecrypt:
boolean lock = boolean lock =
(EntityMessage.PGP_SIGNENCRYPT.equals(message.ui_encrypt) && (EntityMessage.PGP_SIGNENCRYPT.equals(message.ui_encrypt) &&
@ -2370,6 +2328,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
else else
onActionDecrypt(message, false); onActionDecrypt(message, false);
break; break;
case R.id.ibVerify:
onActionDecrypt(message, false);
break;
case R.id.ibUndo:
onActionUndo(message);
break;
case R.id.ibMore:
onActionMore(message);
break;
case R.id.ibDownloading: case R.id.ibDownloading:
Helper.viewFAQ(context, 15); Helper.viewFAQ(context, 15);
@ -2486,39 +2453,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
} }
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
final TupleMessageEx message = getMessage();
if (message == null)
return false;
switch (item.getItemId()) {
case R.id.action_more:
onActionMore(message);
return true;
case R.id.action_delete:
onActionDelete(message);
return true;
case R.id.action_move:
if (EntityFolder.OUTBOX.equals(message.folderType))
onActionMoveOutbox(message);
else
onActionMove(message, false);
return true;
case R.id.action_archive:
if (EntityFolder.JUNK.equals(message.folderType))
onActionMoveJunk(message);
else
onActionArchive(message);
return true;
case R.id.action_reply:
onActionReplyMenu(message);
return true;
default:
return false;
}
}
@Override @Override
public boolean onLongClick(View view) { public boolean onLongClick(View view) {
final TupleMessageEx message = getMessage(); final TupleMessageEx message = getMessage();
@ -3050,170 +2984,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
.putExtra("type", encrypt)); .putExtra("type", encrypt));
} }
private void onActionReplyMenu(TupleMessageEx message) {
Bundle args = new Bundle();
args.putSerializable("message", message);
new SimpleTask<List<TupleIdentityEx>>() {
@Override
protected List<TupleIdentityEx> onExecute(Context context, Bundle args) {
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
if (message == null)
return null;
DB db = DB.getInstance(context);
return db.identity().getComposableIdentities(message.account);
}
@Override
protected void onExecuted(Bundle args, List<TupleIdentityEx> identities) {
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
TupleMessageEx amessage = getMessage();
if (amessage == null || !amessage.id.equals(message.id))
return;
final Address[] to =
message.replySelf(identities, message.account)
? message.to
: (message.reply == null || message.reply.length == 0 ? message.from : message.reply);
Address[] recipients = message.getAllRecipients(identities, message.account);
View anchor = bnvActions.findViewById(R.id.action_reply);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, anchor);
popupMenu.inflate(R.menu.popup_reply);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients.length > 0);
popupMenu.getMenu().findItem(R.id.menu_reply_list).setVisible(message.list_post != null);
popupMenu.getMenu().findItem(R.id.menu_reply_receipt).setVisible(message.receipt_to != null);
popupMenu.getMenu().findItem(R.id.menu_new_message).setVisible(to != null && to.length > 0);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !ActivityBilling.isPro(context));
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
switch (target.getItemId()) {
case R.id.menu_reply_to_sender:
onMenuReply(message, "reply");
return true;
case R.id.menu_reply_to_all:
onMenuReply(message, "reply_all");
return true;
case R.id.menu_reply_list:
onMenuReply(message, "list");
return true;
case R.id.menu_reply_receipt:
onMenuReply(message, "receipt");
return true;
case R.id.menu_forward:
onMenuReply(message, "forward");
return true;
case R.id.menu_editasnew:
onMenuEditAsNew(message);
return true;
case R.id.menu_new_message:
onMenuNew(message, to);
return true;
case R.id.menu_reply_answer:
onMenuAnswer(message);
return true;
default:
return false;
}
}
});
popupMenu.show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(parentFragment.getParentFragmentManager(), ex);
}
}.execute(context, owner, args, "message:reply");
}
private void onMenuReply(TupleMessageEx message, String action) {
Intent reply = new Intent(context, ActivityCompose.class)
.putExtra("action", action)
.putExtra("reference", message.id);
context.startActivity(reply);
}
private void onMenuEditAsNew(final TupleMessageEx message) {
Intent asnew = new Intent(context, ActivityCompose.class)
.putExtra("action", "editasnew")
.putExtra("reference", message.id);
context.startActivity(asnew);
}
private void onMenuNew(TupleMessageEx message, Address[] to) {
Intent reply = new Intent(context, ActivityCompose.class)
.putExtra("action", "new")
.putExtra("to", MessageHelper.formatAddresses(to, true, true));
context.startActivity(reply);
}
private void onMenuAnswer(TupleMessageEx message) {
new SimpleTask<List<EntityAnswer>>() {
@Override
protected List<EntityAnswer> onExecute(Context context, Bundle args) {
return DB.getInstance(context).answer().getAnswers(false);
}
@Override
protected void onExecuted(Bundle args, List<EntityAnswer> answers) {
if (answers == null || answers.size() == 0) {
Snackbar snackbar = Snackbar.make(
parentFragment.getView(),
context.getString(R.string.title_no_answers),
Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override
public void onClick(View v) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
lbm.sendBroadcast(new Intent(ActivityView.ACTION_EDIT_ANSWERS));
}
});
snackbar.show();
} else {
View anchor = bnvActions.findViewById(R.id.action_reply);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, anchor);
int order = 0;
for (EntityAnswer answer : answers)
popupMenu.getMenu().add(Menu.NONE, answer.id.intValue(), order++, answer.toString());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
if (!ActivityBilling.isPro(context)) {
context.startActivity(new Intent(context, ActivityBilling.class));
return true;
}
context.startActivity(new Intent(context, ActivityCompose.class)
.putExtra("action", "reply")
.putExtra("reference", message.id)
.putExtra("answer", (long) target.getItemId()));
return true;
}
});
popupMenu.show();
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(parentFragment.getParentFragmentManager(), ex);
}
}.execute(context, owner, new Bundle(), "message:answer");
}
private void onActionArchive(TupleMessageEx message) {
properties.move(message.id, EntityFolder.ARCHIVE);
}
private void onActionMove(TupleMessageEx message, final boolean copy) { private void onActionMove(TupleMessageEx message, final boolean copy) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("title", context.getString(copy ? R.string.title_copy_to : R.string.title_move_to_folder)); args.putString("title", context.getString(copy ? R.string.title_copy_to : R.string.title_move_to_folder));
@ -3229,7 +2999,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
fragment.show(parentFragment.getParentFragmentManager(), "message:move"); fragment.show(parentFragment.getParentFragmentManager(), "message:move");
} }
private void onActionMoveOutbox(TupleMessageEx message) { private void onActionUndo(TupleMessageEx message) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("id", message.id); args.putLong("id", message.id);
@ -3296,30 +3066,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}.execute(context, owner, args, "message:move:draft"); }.execute(context, owner, args, "message:move:draft");
} }
private void onActionMoveJunk(TupleMessageEx message) { private void onActionNoJunk(TupleMessageEx message) {
properties.move(message.id, EntityFolder.INBOX); properties.move(message.id, EntityFolder.INBOX);
} }
private void onActionDelete(TupleMessageEx message) {
if (delete) {
Bundle aargs = new Bundle();
aargs.putString("question", context.getString(R.string.title_ask_delete));
aargs.putLong("id", message.id);
FragmentDialogAsk ask = new FragmentDialogAsk();
ask.setArguments(aargs);
ask.setTargetFragment(parentFragment, FragmentMessages.REQUEST_MESSAGE_DELETE);
ask.show(parentFragment.getParentFragmentManager(), "message:delete");
} else
properties.move(message.id, EntityFolder.TRASH);
}
private void onActionMore(TupleMessageEx message) { private void onActionMore(TupleMessageEx message) {
boolean show_headers = properties.getValue("headers", message.id); boolean show_headers = properties.getValue("headers", message.id);
boolean full = properties.getValue("full", message.id); boolean full = properties.getValue("full", message.id);
View anchor = bnvActions.findViewById(R.id.action_more); PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, ibMore);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, anchor);
popupMenu.inflate(R.menu.popup_message_more); popupMenu.inflate(R.menu.popup_message_more);
popupMenu.getMenu().findItem(R.id.menu_unseen).setTitle(message.ui_seen ? R.string.title_unseen : R.string.title_seen); popupMenu.getMenu().findItem(R.id.menu_unseen).setTitle(message.ui_seen ? R.string.title_unseen : R.string.title_seen);
@ -3336,6 +3091,12 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
popupMenu.getMenu().findItem(R.id.menu_set_importance_normal).setEnabled(!EntityMessage.PRIORITIY_NORMAL.equals(i)); popupMenu.getMenu().findItem(R.id.menu_set_importance_normal).setEnabled(!EntityMessage.PRIORITIY_NORMAL.equals(i));
popupMenu.getMenu().findItem(R.id.menu_set_importance_high).setEnabled(!EntityMessage.PRIORITIY_HIGH.equals(i)); popupMenu.getMenu().findItem(R.id.menu_set_importance_high).setEnabled(!EntityMessage.PRIORITIY_HIGH.equals(i));
popupMenu.getMenu().findItem(R.id.menu_no_junk).setEnabled(message.uid != null && !message.folderReadOnly);
popupMenu.getMenu().findItem(R.id.menu_no_junk).setVisible(EntityFolder.JUNK.equals(message.folderType));
popupMenu.getMenu().findItem(R.id.menu_move).setEnabled(message.uid != null && !message.folderReadOnly);
popupMenu.getMenu().findItem(R.id.menu_move).setVisible(message.accountProtocol == EntityAccount.TYPE_IMAP);
popupMenu.getMenu().findItem(R.id.menu_copy).setEnabled(message.uid != null && !message.folderReadOnly); popupMenu.getMenu().findItem(R.id.menu_copy).setEnabled(message.uid != null && !message.folderReadOnly);
popupMenu.getMenu().findItem(R.id.menu_copy).setVisible(message.accountProtocol == EntityAccount.TYPE_IMAP); popupMenu.getMenu().findItem(R.id.menu_copy).setVisible(message.accountProtocol == EntityAccount.TYPE_IMAP);
@ -3391,6 +3152,12 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.menu_set_importance_high: case R.id.menu_set_importance_high:
onMenuSetImportance(message, EntityMessage.PRIORITIY_HIGH); onMenuSetImportance(message, EntityMessage.PRIORITIY_HIGH);
return true; return true;
case R.id.menu_no_junk:
onActionNoJunk(message);
return true;
case R.id.menu_move:
onActionMove(message, false);
return true;
case R.id.menu_copy: case R.id.menu_copy:
onActionMove(message, true); onActionMove(message, true);
return true; return true;
@ -4164,14 +3931,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
context.getString(R.string.title_accessibility_view_help))); context.getString(R.string.title_accessibility_view_help)));
ibHelp.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); ibHelp.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
if (expanded && bnvActions != null)
for (int i = 0; i < bnvActions.getMenu().size(); i++) {
MenuItem menuItem = bnvActions.getMenu().getItem(i);
if (menuItem.isVisible() && menuItem.isEnabled())
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
menuItem.getItemId(), menuItem.getTitle()));
}
info.setContentDescription(populateContentDescription(message)); info.setContentDescription(populateContentDescription(message));
} }
@ -4203,14 +3962,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
onHelp(message); onHelp(message);
return true; return true;
default: default:
if (expanded)
for (int i = 0; i < bnvActions.getMenu().size(); i++) {
MenuItem menuItem = bnvActions.getMenu().getItem(i);
if (menuItem.getItemId() == action) {
bnvActions.getMenu().performIdentifierAction(action, 0);
return true;
}
}
return super.performAccessibilityAction(host, action, args); return super.performAccessibilityAction(host, action, args);
} }
} }
@ -4829,11 +4580,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
} }
void setAnswerCount(int answers) {
this.answers = answers;
Log.i("Answer count=" + answers);
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return differ.getItemCount(); return differ.getItemCount();

@ -43,7 +43,7 @@ public interface DaoAnswer {
@Query("SELECT COUNT(*) FROM answer" + @Query("SELECT COUNT(*) FROM answer" +
" WHERE NOT hide") " WHERE NOT hide")
LiveData<Integer> liveAnswerCount(); Integer getAnswerCount();
@Insert @Insert
long insertAnswer(EntityAnswer answer); long insertAnswer(EntityAnswer answer);

@ -891,75 +891,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
fabReply.setOnClickListener(new View.OnClickListener() { fabReply.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (values.containsKey("expanded") && values.get("expanded").size() > 0) { onReply();
Bundle args = new Bundle();
args.putLong("id", values.get("expanded").get(0));
new SimpleTask<Integer>() {
@Override
protected Integer onExecute(Context context, Bundle args) {
long id = args.getLong("id");
DB db = DB.getInstance(context);
EntityMessage message = db.message().getMessage(id);
if (message == null)
return null;
List<TupleIdentityEx> identities = db.identity().getComposableIdentities(message.account);
if (identities == null)
return null;
Address[] recipients = message.getAllRecipients(identities, message.account);
return recipients.length;
}
@Override
protected void onExecuted(Bundle args, Integer recipients) {
if (recipients == null)
return;
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), fabReply);
popupMenu.inflate(R.menu.popup_reply);
for (int i = 0; i < popupMenu.getMenu().size(); i++)
popupMenu.getMenu().getItem(i).setVisible(false);
popupMenu.getMenu().findItem(R.id.menu_reply_to_sender).setVisible(true);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients > 1);
popupMenu.getMenu().findItem(R.id.menu_forward).setVisible(true);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
switch (target.getItemId()) {
case R.id.menu_reply_to_sender:
onReply("reply");
return true;
case R.id.menu_reply_to_all:
onReply("reply_all");
return true;
case R.id.menu_forward:
onReply("forward");
return true;
default:
return false;
}
}
});
popupMenu.show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(FragmentMessages.this, args, "messages:reply");
}
}
});
fabReply.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
return onReply("reply_all");
} }
}); });
@ -2035,7 +1967,164 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
}; };
private boolean onReply(String action) { private void onReply() {
if (values.containsKey("expanded") && values.get("expanded").size() > 0) {
long id = values.get("expanded").get(0);
int pos = adapter.getPositionForKey(id);
TupleMessageEx message = adapter.getItemAtPosition(pos);
Bundle args = new Bundle();
args.putLong("id", id);
new SimpleTask<List<TupleIdentityEx>>() {
@Override
protected List<TupleIdentityEx> onExecute(Context context, Bundle args) {
long id = args.getLong("id");
DB db = DB.getInstance(context);
EntityMessage message = db.message().getMessage(id);
if (message == null)
return null;
args.putInt("answers", db.answer().getAnswerCount());
return db.identity().getComposableIdentities(message.account);
}
@Override
protected void onExecuted(Bundle args, List<TupleIdentityEx> identities) {
if (identities == null)
identities = new ArrayList<>();
final Address[] to =
message.replySelf(identities, message.account)
? message.to
: (message.reply == null || message.reply.length == 0 ? message.from : message.reply);
Address[] recipients = message.getAllRecipients(identities, message.account);
int answers = args.getInt("answers");
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), fabReply);
popupMenu.inflate(R.menu.popup_reply);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients.length > 0);
popupMenu.getMenu().findItem(R.id.menu_reply_list).setVisible(message.list_post != null);
popupMenu.getMenu().findItem(R.id.menu_reply_receipt).setVisible(message.receipt_to != null);
popupMenu.getMenu().findItem(R.id.menu_new_message).setVisible(to != null && to.length > 0);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !ActivityBilling.isPro(getContext()));
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
switch (target.getItemId()) {
case R.id.menu_reply_to_sender:
onMenuReply(message, "reply");
return true;
case R.id.menu_reply_to_all:
onMenuReply(message, "reply_all");
return true;
case R.id.menu_reply_list:
onMenuReply(message, "list");
return true;
case R.id.menu_reply_receipt:
onMenuReply(message, "receipt");
return true;
case R.id.menu_forward:
onMenuReply(message, "forward");
return true;
case R.id.menu_editasnew:
onMenuReply(message, "editasnew");
return true;
case R.id.menu_new_message:
onMenuNew(message, to);
return true;
case R.id.menu_reply_answer:
onMenuAnswer(message);
return true;
default:
return false;
}
}
});
popupMenu.show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(FragmentMessages.this, args, "messages:reply");
}
}
private void onMenuReply(TupleMessageEx message, String action) {
Intent reply = new Intent(getContext(), ActivityCompose.class)
.putExtra("action", action)
.putExtra("reference", message.id);
startActivity(reply);
}
private void onMenuNew(TupleMessageEx message, Address[] to) {
Intent reply = new Intent(getContext(), ActivityCompose.class)
.putExtra("action", "new")
.putExtra("to", MessageHelper.formatAddresses(to, true, true));
startActivity(reply);
}
private void onMenuAnswer(TupleMessageEx message) {
new SimpleTask<List<EntityAnswer>>() {
@Override
protected List<EntityAnswer> onExecute(Context context, Bundle args) {
return DB.getInstance(context).answer().getAnswers(false);
}
@Override
protected void onExecuted(Bundle args, List<EntityAnswer> answers) {
if (answers == null || answers.size() == 0) {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_answers, Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override
public void onClick(View v) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
lbm.sendBroadcast(new Intent(ActivityView.ACTION_EDIT_ANSWERS));
}
});
snackbar.show();
} else {
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), fabReply);
int order = 0;
for (EntityAnswer answer : answers)
popupMenu.getMenu().add(Menu.NONE, answer.id.intValue(), order++, answer.toString());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
if (!ActivityBilling.isPro(getContext())) {
startActivity(new Intent(getContext(), ActivityBilling.class));
return true;
}
startActivity(new Intent(getContext(), ActivityCompose.class)
.putExtra("action", "reply")
.putExtra("reference", message.id)
.putExtra("answer", (long) target.getItemId()));
return true;
}
});
popupMenu.show();
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(getContext(), getViewLifecycleOwner(), new Bundle(), "message:answer");
}
private boolean _onReply(String action) {
if (values.containsKey("expanded") && values.get("expanded").size() > 0) { if (values.containsKey("expanded") && values.get("expanded").size() > 0) {
Context context = getContext(); Context context = getContext();
if (context == null) if (context == null)
@ -2803,13 +2892,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
}); });
db.answer().liveAnswerCount().observe(getViewLifecycleOwner(), new Observer<Integer>() {
@Override
public void onChanged(Integer count) {
adapter.setAnswerCount(count == null ? -1 : count);
}
});
// Folder // Folder
switch (viewType) { switch (viewType) {
case UNIFIED: case UNIFIED:

@ -5,7 +5,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<View <View
android:id="@+id/vSeparatorTop" android:id="@+id/vSeparator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
@ -13,27 +13,20 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView <ImageButton
android:id="@+id/bnvActions" android:id="@+id/ibMore"
android:layout_width="0dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:background="@android:color/transparent" android:layout_marginEnd="12dp"
app:elevation="0dp" android:background="?android:attr/selectableItemBackgroundBorderless"
app:itemIconTint="?android:attr/textColorSecondary" android:contentDescription="@string/title_more"
app:itemTextColor="?android:attr/textColorSecondary" android:foregroundTint="?android:attr/textColorSecondary"
app:labelVisibilityMode="unlabeled" android:padding="3dp"
app:layout_constraintEnd_toEndOf="parent" android:scaleType="fitCenter"
app:layout_constraintStart_toStartOf="parent" android:tooltipText="@string/title_more"
app:layout_constraintTop_toBottomOf="@+id/vSeparatorTop"
app:menu="@menu/action_message" />
<View
android:id="@+id/vSeparatorBottom"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorSeparator"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bnvActions" /> app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_more_vert_24" />
<eu.faircode.email.ContentLoadingProgressBar <eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbBody" android:id="@+id/pbBody"
@ -43,14 +36,28 @@
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:indeterminate="true" android:indeterminate="true"
app:layout_constraintBottom_toBottomOf="@+id/ibFull" app:layout_constraintBottom_toBottomOf="@+id/ibFull"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toEndOf="@id/ibMore"
app:layout_constraintTop_toTopOf="@+id/ibFull" /> app:layout_constraintTop_toTopOf="@+id/ibFull" />
<ImageButton
android:id="@+id/ibUndo"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_undo"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="3dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_undo"
app:layout_constraintEnd_toStartOf="@+id/ibVerify"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_undo_24" />
<ImageButton <ImageButton
android:id="@+id/ibVerify" android:id="@+id/ibVerify"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_sign" android:contentDescription="@string/title_sign"
@ -59,14 +66,13 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_sign" android:tooltipText="@string/title_sign"
app:layout_constraintEnd_toStartOf="@+id/ibDecrypt" app:layout_constraintEnd_toStartOf="@+id/ibDecrypt"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_gesture_24" /> app:srcCompat="@drawable/baseline_gesture_24" />
<ImageButton <ImageButton
android:id="@+id/ibDecrypt" android:id="@+id/ibDecrypt"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_decrypt" android:contentDescription="@string/title_decrypt"
@ -75,14 +81,13 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_decrypt" android:tooltipText="@string/title_decrypt"
app:layout_constraintEnd_toStartOf="@+id/ibJunk" app:layout_constraintEnd_toStartOf="@+id/ibJunk"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_lock_open_24" /> app:srcCompat="@drawable/baseline_lock_open_24" />
<ImageButton <ImageButton
android:id="@+id/ibJunk" android:id="@+id/ibJunk"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_junk" android:contentDescription="@string/title_legend_show_junk"
@ -91,14 +96,13 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_junk" android:tooltipText="@string/title_legend_show_junk"
app:layout_constraintEnd_toStartOf="@+id/ibUnsubscribe" app:layout_constraintEnd_toStartOf="@+id/ibUnsubscribe"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_flag_24" /> app:srcCompat="@drawable/baseline_flag_24" />
<ImageButton <ImageButton
android:id="@+id/ibUnsubscribe" android:id="@+id/ibUnsubscribe"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_unsubscribe" android:contentDescription="@string/title_legend_show_unsubscribe"
@ -107,14 +111,13 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_unsubscribe" android:tooltipText="@string/title_legend_show_unsubscribe"
app:layout_constraintEnd_toStartOf="@+id/ibImages" app:layout_constraintEnd_toStartOf="@+id/ibImages"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_unsubscribe_24" /> app:srcCompat="@drawable/baseline_unsubscribe_24" />
<ImageButton <ImageButton
android:id="@+id/ibImages" android:id="@+id/ibImages"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_images" android:contentDescription="@string/title_legend_show_images"
@ -123,14 +126,13 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_images" android:tooltipText="@string/title_legend_show_images"
app:layout_constraintEnd_toStartOf="@+id/ibFull" app:layout_constraintEnd_toStartOf="@+id/ibFull"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_image_24" /> app:srcCompat="@drawable/baseline_image_24" />
<ImageButton <ImageButton
android:id="@+id/ibFull" android:id="@+id/ibFull"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_full" android:contentDescription="@string/title_legend_show_full"
android:foregroundTint="?android:attr/textColorSecondary" android:foregroundTint="?android:attr/textColorSecondary"
@ -138,7 +140,7 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_full" android:tooltipText="@string/title_legend_show_full"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBottom" app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_fullscreen_24" /> app:srcCompat="@drawable/baseline_fullscreen_24" />
<eu.faircode.email.FixedTextView <eu.faircode.email.FixedTextView
@ -151,10 +153,4 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibVerify" /> app:layout_constraintTop_toBottomOf="@id/ibVerify" />
<androidx.constraintlayout.widget.Group
android:id="@+id/grpActions"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="vSeparatorTop,bnvActions,vSeparatorBottom" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_more"
android:icon="@drawable/baseline_more_vert_24"
android:title="@string/title_more" />
<item
android:id="@+id/action_delete"
android:icon="@drawable/baseline_delete_24"
android:title="@string/title_trash" />
<item
android:id="@+id/action_move"
android:icon="@drawable/baseline_folder_24"
android:title="@string/title_move" />
<item
android:id="@+id/action_archive"
android:icon="@drawable/baseline_archive_24"
android:title="@string/title_archive" />
<item
android:id="@+id/action_reply"
android:icon="@drawable/baseline_reply_all_24"
android:title="@string/title_reply" />
</menu>

@ -32,6 +32,14 @@
</menu> </menu>
</item> </item>
<item
android:id="@+id/menu_no_junk"
android:title="@string/title_no_junk" />
<item
android:id="@+id/menu_move"
android:title="@string/title_move_to" />
<item <item
android:id="@+id/menu_copy" android:id="@+id/menu_copy"
android:title="@string/title_copy" /> android:title="@string/title_copy" />

@ -677,6 +677,8 @@
<string name="title_more">More</string> <string name="title_more">More</string>
<string name="title_spam">Spam</string> <string name="title_spam">Spam</string>
<string name="title_move">Move</string> <string name="title_move">Move</string>
<string name="title_no_junk">Not spam</string>
<string name="title_move_to">Move to &#8230;</string>
<string name="title_move_to_folder">Move to &#8230;</string> <string name="title_move_to_folder">Move to &#8230;</string>
<string name="title_move_to_account">Move to %1$s &#8230;</string> <string name="title_move_to_account">Move to %1$s &#8230;</string>
<string name="title_snooze">Snooze &#8230;</string> <string name="title_snooze">Snooze &#8230;</string>

Loading…
Cancel
Save