Reorganized action buttons

pull/175/head
M66B 5 years ago
parent 9caf8da109
commit df1649f875

@ -383,6 +383,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private ImageButton ibDecrypt;
private ImageButton ibVerify;
private ImageButton ibUndo;
private ImageButton ibAnswer;
private ImageButton ibMove;
private ImageButton ibArchive;
private ImageButton ibTrash;
private ImageButton ibJunk;
@ -390,8 +392,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private ImageButton ibMore;
private TextView tvSignedData;
private TextView tvCrossHint;
private ImageButton ibAnswerHint;
private TextView tvAnswerHint;
private TextView tvBody;
private View wvBody;
@ -572,6 +572,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibDecrypt = vsBody.findViewById(R.id.ibDecrypt);
ibVerify = vsBody.findViewById(R.id.ibVerify);
ibUndo = vsBody.findViewById(R.id.ibUndo);
ibAnswer = vsBody.findViewById(R.id.ibAnswer);
ibMove = vsBody.findViewById(R.id.ibMove);
ibArchive = vsBody.findViewById(R.id.ibArchive);
ibTrash = vsBody.findViewById(R.id.ibTrash);
ibJunk = vsBody.findViewById(R.id.ibJunk);
@ -579,8 +581,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibMore = vsBody.findViewById(R.id.ibMore);
tvSignedData = vsBody.findViewById(R.id.tvSignedData);
tvCrossHint = vsBody.findViewById(R.id.tvCrossHint);
ibAnswerHint = vsBody.findViewById(R.id.ibAnswerHint);
tvAnswerHint = vsBody.findViewById(R.id.tvAnswerHint);
tvBody = vsBody.findViewById(R.id.tvBody);
wvBody = vsBody.findViewById(R.id.wvBody);
@ -656,12 +656,13 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibDecrypt.setOnClickListener(this);
ibVerify.setOnClickListener(this);
ibUndo.setOnClickListener(this);
ibAnswer.setOnClickListener(this);
ibMove.setOnClickListener(this);
ibArchive.setOnClickListener(this);
ibTrash.setOnClickListener(this);
ibJunk.setOnClickListener(this);
ibRemove.setOnClickListener(this);
ibMore.setOnClickListener(this);
ibAnswerHint.setOnClickListener(this);
ibDownloading.setOnClickListener(this);
@ -728,12 +729,13 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibDecrypt.setOnClickListener(null);
ibVerify.setOnClickListener(null);
ibUndo.setOnClickListener(null);
ibAnswer.setOnClickListener(null);
ibMove.setOnClickListener(null);
ibArchive.setOnClickListener(null);
ibTrash.setOnClickListener(null);
ibJunk.setOnClickListener(null);
ibRemove.setOnClickListener(null);
ibMore.setOnClickListener(null);
ibAnswerHint.setOnClickListener(null);
ibDownloading.setOnClickListener(null);
@ -1159,6 +1161,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibDecrypt.setVisibility(View.GONE);
ibVerify.setVisibility(View.GONE);
ibUndo.setVisibility(View.GONE);
ibAnswer.setVisibility(View.GONE);
ibMove.setVisibility(View.GONE);
ibArchive.setVisibility(View.GONE);
ibTrash.setVisibility(View.GONE);
ibJunk.setVisibility(View.GONE);
@ -1166,8 +1170,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibMore.setVisibility(View.GONE);
tvSignedData.setVisibility(View.GONE);
tvCrossHint.setVisibility(View.GONE);
ibAnswerHint.setVisibility(View.GONE);
tvAnswerHint.setVisibility(View.GONE);
tvBody.setVisibility(View.GONE);
wvBody.setVisibility(View.GONE);
@ -1312,7 +1314,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean cross_hint = prefs.getBoolean("cross_hint", true);
boolean answer_hint = prefs.getBoolean("answer_hint", false);
boolean normal = context.getResources().getConfiguration()
.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_NORMAL);
@ -1325,13 +1326,13 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibVerify.setVisibility(View.GONE);
ibUndo.setVisibility(EntityFolder.OUTBOX.equals(message.folderType) ? View.VISIBLE : View.GONE);
ibAnswer.setVisibility(normal ? View.GONE : View.VISIBLE);
ibMove.setVisibility(normal || message.folderReadOnly || message.uid == null ? View.GONE : View.VISIBLE);
ibArchive.setVisibility(View.GONE);
ibTrash.setVisibility(View.GONE);
ibJunk.setVisibility(View.GONE);
ibRemove.setVisibility(normal || message.folderReadOnly ? View.GONE : View.VISIBLE);
tvCrossHint.setVisibility(!normal && cross_hint ? View.VISIBLE : View.GONE);
ibAnswerHint.setVisibility(answer_hint ? View.VISIBLE : View.GONE);
tvAnswerHint.setVisibility(answer_hint ? View.VISIBLE : View.GONE);
if (normal)
onActionRemove(message, true);
@ -2321,6 +2322,12 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.ibUndo:
onActionUndo(message);
break;
case R.id.ibAnswer:
onActionAnswer(message, ibAnswer);
break;
case R.id.ibMove:
onActionMove(message, false);
break;
case R.id.ibArchive:
onActionArchive(message);
break;
@ -2339,9 +2346,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.ibMore:
onActionMore(message);
break;
case R.id.ibAnswerHint:
onActionAnswerHint();
break;
case R.id.ibDownloading:
Helper.viewFAQ(context, 15);
@ -2979,6 +2983,10 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
.putExtra("type", encrypt));
}
private void onActionAnswer(TupleMessageEx message, View anchor) {
((FragmentMessages) parentFragment).onReply(message, anchor);
}
private void onActionMove(TupleMessageEx message, final boolean copy) {
Bundle args = new Bundle();
args.putString("title", context.getString(copy ? R.string.title_copy_to : R.string.title_move_to_folder));
@ -3113,10 +3121,11 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
boolean inJunk = EntityFolder.JUNK.equals(message.folderType);
boolean outbox = EntityFolder.OUTBOX.equals(message.folderType);
boolean archive = (!message.folderReadOnly && message.uid != null && (hasArchive && !inArchive));
boolean trash = ((!message.folderReadOnly && message.uid != null) || outbox || debug);
boolean junk = (!message.folderReadOnly && message.uid != null && (hasJunk && !inJunk));
boolean unjunk = (!message.folderReadOnly && message.uid != null && inJunk);
boolean move = !(message.folderReadOnly || message.uid == null);
boolean archive = (move && (hasArchive && !inArchive));
boolean trash = (move || outbox || debug);
boolean junk = (move && (hasJunk && !inJunk));
boolean unjunk = (move && inJunk);
final boolean delete = (inTrash || !hasTrash || outbox || message.uid == null);
@ -3128,6 +3137,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
ibJunk.setTooltipText(title);
ibAnswer.setVisibility(View.VISIBLE);
ibMove.setVisibility(move ? View.VISIBLE : View.GONE);
ibArchive.setVisibility(archive ? View.VISIBLE : View.GONE);
ibTrash.setVisibility(trash ? View.VISIBLE : View.GONE);
ibJunk.setVisibility(junk || unjunk ? View.VISIBLE : View.GONE);
@ -3237,9 +3248,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
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).setVisible(message.accountProtocol == EntityAccount.TYPE_IMAP);
@ -3298,9 +3306,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
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:
onActionMove(message, true);
return true;
@ -3342,13 +3347,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
popupMenu.show();
}
private void onActionAnswerHint() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean("answer_hint", false).apply();
ibAnswerHint.setVisibility(View.GONE);
tvAnswerHint.setVisibility(View.GONE);
}
private class TouchHandler extends ArrowKeyMovementMethod {
private TupleMessageEx message;

@ -1976,95 +1976,98 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
TupleMessageEx message = adapter.getItemAtPosition(pos);
if (message == null)
return;
onReply(message, fabReply);
}
}
Bundle args = new Bundle();
args.putLong("id", id);
void onReply(final TupleMessageEx message, final View anchor) {
Bundle args = new Bundle();
args.putLong("id", message.id);
new SimpleTask<List<TupleIdentityEx>>() {
@Override
protected List<TupleIdentityEx> onExecute(Context context, Bundle args) {
long id = args.getLong("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;
DB db = DB.getInstance(context);
EntityMessage message = db.message().getMessage(id);
if (message == null)
return null;
args.putInt("answers", db.answer().getAnswerCount());
args.putInt("answers", db.answer().getAnswerCount());
return db.identity().getComposableIdentities(message.account);
}
return db.identity().getComposableIdentities(message.account);
}
@Override
protected void onExecuted(Bundle args, List<TupleIdentityEx> identities) {
if (identities == null)
identities = new ArrayList<>();
@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);
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);
Address[] recipients = message.getAllRecipients(identities, message.account);
int answers = args.getInt("answers");
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.getMenu().findItem(R.id.menu_reply_to_sender).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_forward).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_editasnew).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setEnabled(message.content);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), 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(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.getMenu().findItem(R.id.menu_reply_to_sender).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_forward).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_editasnew).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setEnabled(message.content);
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();
}
}
});
popupMenu.show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(FragmentMessages.this, args, "messages:reply");
}
@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) {

@ -49,7 +49,6 @@
android:tooltipText="@string/title_delete"
app:layout_constraintStart_toEndOf="@id/ibMore"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:layout_goneMarginStart="0dp"
app:srcCompat="@drawable/baseline_close_24" />
<ImageButton
@ -63,9 +62,8 @@
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_spam"
app:layout_constraintStart_toEndOf="@id/ibMore"
app:layout_constraintStart_toEndOf="@id/ibRemove"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:layout_goneMarginStart="0dp"
app:srcCompat="@drawable/baseline_flag_24" />
<ImageButton
@ -81,7 +79,6 @@
android:tooltipText="@string/title_delete"
app:layout_constraintStart_toEndOf="@id/ibJunk"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:layout_goneMarginStart="0dp"
app:srcCompat="@drawable/baseline_delete_24" />
<ImageButton
@ -97,53 +94,52 @@
android:tooltipText="@string/title_archive"
app:layout_constraintStart_toEndOf="@id/ibTrash"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:layout_goneMarginStart="0dp"
app:srcCompat="@drawable/baseline_archive_24" />
<ImageButton
android:id="@+id/ibUndo"
android:id="@+id/ibMove"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="9dp"
android:layout_marginStart="9dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_undo"
android:contentDescription="@string/title_move"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_undo"
app:layout_constraintEnd_toStartOf="@+id/ibVerify"
android:tooltipText="@string/title_move"
app:layout_constraintStart_toEndOf="@id/ibArchive"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_undo_24" />
app:srcCompat="@drawable/baseline_folder_24" />
<ImageButton
android:id="@+id/ibVerify"
android:id="@+id/ibAnswer"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="9dp"
android:layout_marginStart="9dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_sign"
android:contentDescription="@string/title_reply"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_sign"
app:layout_constraintEnd_toStartOf="@+id/ibDecrypt"
android:tooltipText="@string/title_reply"
app:layout_constraintStart_toEndOf="@id/ibMove"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_gesture_24" />
app:srcCompat="@drawable/baseline_reply_24" />
<ImageButton
android:id="@+id/ibDecrypt"
android:id="@+id/ibUndo"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="9dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_decrypt"
android:contentDescription="@string/title_undo"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_decrypt"
android:tooltipText="@string/title_undo"
app:layout_constraintEnd_toStartOf="@+id/ibUnsubscribe"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_lock_open_24" />
app:srcCompat="@drawable/baseline_undo_24" />
<ImageButton
android:id="@+id/ibUnsubscribe"
@ -189,6 +185,35 @@
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_fullscreen_24" />
<ImageButton
android:id="@+id/ibVerify"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="9dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_sign"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_sign"
app:layout_constraintEnd_toStartOf="@+id/ibDecrypt"
app:layout_constraintTop_toBottomOf="@id/ibFull"
app:srcCompat="@drawable/baseline_gesture_24" />
<ImageButton
android:id="@+id/ibDecrypt"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_decrypt"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_decrypt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibFull"
app:srcCompat="@drawable/baseline_lock_open_24" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvSignedData"
android:layout_width="0dp"
@ -198,7 +223,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibFull" />
app:layout_constraintTop_toBottomOf="@id/ibVerify" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvCrossHint"
@ -211,28 +236,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/ibRemove"
app:layout_constraintTop_toBottomOf="@id/tvSignedData" />
<ImageButton
android:id="@+id/ibAnswerHint"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_close_hint"
app:layout_constraintBottom_toBottomOf="@id/tvAnswerHint"
app:layout_constraintEnd_toStartOf="@+id/tvAnswerHint"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tvAnswerHint"
app:srcCompat="@drawable/baseline_close_24" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvAnswerHint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/title_answer_hint"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ibAnswerHint"
app:layout_constraintTop_toBottomOf="@id/tvCrossHint" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -36,10 +36,6 @@
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
android:id="@+id/menu_copy"
android:title="@string/title_copy_to" />

@ -745,7 +745,6 @@
<string name="title_ask_reporting">Send error reports?</string>
<string name="title_reporting_why">Error reporting will help improve FairEmail</string>
<string name="title_message_bar_hint">Tap the cross icon to archive, delete or report a message as spam and to remove this notice</string>
<string name="title_answer_hint">Reply to all, forwarding, etc. have been moved to the reply button at the bottom</string>
<string name="title_ask_review">Please review FairEmail</string>
<string name="title_ask_review_rationale">

Loading…
Cancel
Save