Flow message actions

pull/175/head
M66B 5 years ago
parent eafc1197f2
commit 504c0897e9

@ -387,10 +387,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private ImageButton ibArchive;
private ImageButton ibTrash;
private ImageButton ibJunk;
private ImageButton ibRemove;
private ImageButton ibMore;
private TextView tvSignedData;
private TextView tvCrossHint;
private TextView tvBody;
private View wvBody;
@ -577,10 +575,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibArchive = vsBody.findViewById(R.id.ibArchive);
ibTrash = vsBody.findViewById(R.id.ibTrash);
ibJunk = vsBody.findViewById(R.id.ibJunk);
ibRemove = vsBody.findViewById(R.id.ibRemove);
ibMore = vsBody.findViewById(R.id.ibMore);
tvSignedData = vsBody.findViewById(R.id.tvSignedData);
tvCrossHint = vsBody.findViewById(R.id.tvCrossHint);
tvBody = vsBody.findViewById(R.id.tvBody);
wvBody = vsBody.findViewById(R.id.wvBody);
@ -662,7 +658,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibArchive.setOnClickListener(this);
ibTrash.setOnClickListener(this);
ibJunk.setOnClickListener(this);
ibRemove.setOnClickListener(this);
ibMore.setOnClickListener(this);
ibDownloading.setOnClickListener(this);
@ -736,7 +731,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibArchive.setOnClickListener(null);
ibTrash.setOnClickListener(null);
ibJunk.setOnClickListener(null);
ibRemove.setOnClickListener(null);
ibMore.setOnClickListener(null);
ibDownloading.setOnClickListener(null);
@ -1169,10 +1163,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibArchive.setVisibility(View.GONE);
ibTrash.setVisibility(View.GONE);
ibJunk.setVisibility(View.GONE);
ibRemove.setVisibility(View.GONE);
ibMore.setVisibility(View.GONE);
tvSignedData.setVisibility(View.GONE);
tvCrossHint.setVisibility(View.GONE);
tvBody.setVisibility(View.GONE);
wvBody.setVisibility(View.GONE);
@ -1316,10 +1308,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
tvNoInternetHeaders.setVisibility(View.GONE);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean cross_hint = prefs.getBoolean("cross_hint", true);
boolean normal = (context.getResources().getConfiguration().screenWidthDp >= 9 * 39 - 3);
vSeparator.setVisibility(View.VISIBLE);
ibFull.setEnabled(false);
ibFull.setVisibility(View.VISIBLE);
@ -1328,17 +1316,80 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibVerify.setVisibility(View.GONE);
ibUndo.setVisibility(EntityFolder.OUTBOX.equals(message.folderType) ? View.VISIBLE : View.GONE);
ibUnsubscribe.setVisibility(normal || message.unsubscribe == null ? View.GONE : View.VISIBLE);
ibAnswer.setVisibility(normal || EntityFolder.OUTBOX.equals(message.folderType) ? 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);
// Setup actions
Bundle sargs = new Bundle();
sargs.putLong("id", message.id);
sargs.putLong("account", message.account);
new SimpleTask<List<EntityFolder>>() {
@Override
protected void onPreExecute(Bundle args) {
ibUnsubscribe.setVisibility(View.GONE);
ibAnswer.setVisibility(View.GONE);
ibMove.setVisibility(View.GONE);
ibArchive.setVisibility(View.GONE);
ibTrash.setVisibility(View.GONE);
ibJunk.setVisibility(View.GONE);
}
@Override
protected List<EntityFolder> onExecute(Context context, Bundle args) {
long account = args.getLong("account");
return DB.getInstance(context).folder().getSystemFolders(account);
}
@Override
protected void onExecuted(Bundle args, List<EntityFolder> folders) {
long id = args.getLong("id");
TupleMessageEx amessage = getMessage();
if (amessage == null || !amessage.id.equals(id))
return;
boolean hasArchive = false;
boolean hasTrash = false;
boolean hasJunk = false;
if (folders != null)
for (EntityFolder folder : folders)
if (EntityFolder.ARCHIVE.equals(folder.type))
hasArchive = true;
else if (EntityFolder.TRASH.equals(folder.type))
hasTrash = true;
else if (EntityFolder.JUNK.equals(folder.type))
hasJunk = true;
if (normal)
onActionRemove(message, true);
boolean inArchive = EntityFolder.ARCHIVE.equals(message.folderType);
boolean inTrash = EntityFolder.TRASH.equals(message.folderType);
boolean inJunk = EntityFolder.JUNK.equals(message.folderType);
boolean outbox = EntityFolder.OUTBOX.equals(message.folderType);
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);
ibTrash.setTag(delete);
ibJunk.setImageResource(unjunk ? R.drawable.baseline_inbox_24 : R.drawable.baseline_flag_24);
String title = context.getString(unjunk ? R.string.title_no_junk : R.string.title_spam);
ibJunk.setContentDescription(title);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
ibJunk.setTooltipText(title);
ibUnsubscribe.setVisibility(message.unsubscribe == null ? View.GONE : View.VISIBLE);
ibAnswer.setVisibility(outbox ? View.GONE : 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);
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(parentFragment.getParentFragmentManager(), ex);
}
}.setLog(false).execute(context, owner, sargs, "message:more");
ibMore.setVisibility(EntityFolder.OUTBOX.equals(message.folderType) ? View.GONE : View.VISIBLE);
tvSignedData.setVisibility(View.GONE);
@ -2330,6 +2381,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.ibVerify:
onActionDecrypt(message, false);
break;
case R.id.ibUndo:
onActionUndo(message);
break;
@ -2351,9 +2403,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
else
onActionJunk(message);
break;
case R.id.ibRemove:
onActionRemove(message, false);
break;
case R.id.ibMore:
onActionMore(message);
break;
@ -3087,121 +3136,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
properties.move(message.id, EntityFolder.INBOX);
}
private void onActionRemove(TupleMessageEx message, boolean normal) {
if (!normal) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean("cross_hint", false).apply();
tvCrossHint.setVisibility(View.GONE);
if (EntityFolder.OUTBOX.equals(message.folderType)) {
onActionDelete(message);
return;
}
}
// Setup actions
Bundle sargs = new Bundle();
sargs.putLong("id", message.id);
sargs.putLong("account", message.account);
new SimpleTask<List<EntityFolder>>() {
@Override
protected List<EntityFolder> onExecute(Context context, Bundle args) {
long account = args.getLong("account");
return DB.getInstance(context).folder().getSystemFolders(account);
}
@Override
protected void onExecuted(Bundle args, List<EntityFolder> folders) {
long id = args.getLong("id");
TupleMessageEx amessage = getMessage();
if (amessage == null || !amessage.id.equals(id))
return;
boolean hasArchive = false;
boolean hasTrash = false;
boolean hasJunk = false;
if (folders != null)
for (EntityFolder folder : folders)
if (EntityFolder.ARCHIVE.equals(folder.type))
hasArchive = true;
else if (EntityFolder.TRASH.equals(folder.type))
hasTrash = true;
else if (EntityFolder.JUNK.equals(folder.type))
hasJunk = true;
boolean inArchive = EntityFolder.ARCHIVE.equals(message.folderType);
boolean inTrash = EntityFolder.TRASH.equals(message.folderType);
boolean inJunk = EntityFolder.JUNK.equals(message.folderType);
boolean outbox = EntityFolder.OUTBOX.equals(message.folderType);
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);
if (normal) {
ibTrash.setTag(delete);
ibJunk.setImageResource(unjunk ? R.drawable.baseline_inbox_24 : R.drawable.baseline_flag_24);
String title = context.getString(unjunk ? R.string.title_no_junk : R.string.title_spam);
ibJunk.setContentDescription(title);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
ibJunk.setTooltipText(title);
ibUnsubscribe.setVisibility(message.unsubscribe == null ? View.GONE : View.VISIBLE);
ibAnswer.setVisibility(outbox ? View.GONE : 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);
} else {
if (!hasArchive && !hasJunk) {
if (delete)
onActionDelete(message);
else
properties.move(message.id, EntityFolder.TRASH);
return;
}
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, ibMore);
popupMenu.inflate(R.menu.popup_message_remove);
popupMenu.getMenu().findItem(R.id.menu_archive).setEnabled(archive);
popupMenu.getMenu().findItem(R.id.menu_trash).setEnabled(trash);
popupMenu.getMenu().findItem(R.id.menu_junk).setEnabled(junk);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem target) {
switch (target.getItemId()) {
case R.id.menu_archive:
onActionArchive(message);
return true;
case R.id.menu_trash:
onActionTrash(message, delete);
return true;
case R.id.menu_junk:
onActionJunk(message);
return true;
default:
return false;
}
}
});
popupMenu.show();
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(parentFragment.getParentFragmentManager(), ex);
}
}.setLog(false).execute(context, owner, sargs, "message:more");
}
private void onActionArchive(TupleMessageEx message) {
properties.move(message.id, EntityFolder.ARCHIVE);
}

@ -81,7 +81,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
};
private final static String[] RESET_QUESTIONS = new String[]{
"welcome", "crash_reports_asked", "review_asked", "review_later", "cross_hint", "answer_hint", "why",
"welcome", "crash_reports_asked", "review_asked", "review_later", "why",
"reply_hint", "html_always_images", "print_html_confirmed", "move_1_confirmed", "move_n_confirmed",
"identities_asked", "cc_bcc", "inline_image_hint", "compose_reference", "send_dialog",
"setup_advanced"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -22,6 +23,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/vSeparator" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
app:constraint_referenced_ids="ibMore,ibJunk,ibTrash,ibArchive,ibMove,ibAnswer,ibUnsubscribe,ibUndo"
app:flow_horizontalBias="0"
app:flow_horizontalGap="6dp"
app:flow_horizontalStyle="packed"
app:flow_wrapMode="chain"
app:layout_constraintEnd_toStartOf="@+id/ibVerify"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/vSeparator" />
<ImageButton
android:id="@+id/ibMore"
android:layout_width="36dp"
@ -32,189 +46,158 @@
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_more_vert_24" />
<ImageButton
android:id="@+id/ibRemove"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_delete"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_delete"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/ibMore"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_close_24" />
app:srcCompat="@drawable/baseline_more_vert_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibJunk"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_spam"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_spam"
app:layout_constraintStart_toEndOf="@id/ibRemove"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_flag_24" />
app:srcCompat="@drawable/baseline_flag_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibTrash"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_delete"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_delete"
app:layout_constraintStart_toEndOf="@id/ibJunk"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_delete_24" />
app:srcCompat="@drawable/baseline_delete_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibArchive"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_archive"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_archive"
app:layout_constraintStart_toEndOf="@id/ibTrash"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_archive_24" />
app:srcCompat="@drawable/baseline_archive_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibMove"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_move"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_move"
app:layout_constraintStart_toEndOf="@id/ibArchive"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_folder_24" />
app:srcCompat="@drawable/baseline_folder_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibAnswer"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_reply"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_reply"
app:layout_constraintStart_toEndOf="@id/ibMove"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_reply_24" />
app:srcCompat="@drawable/baseline_reply_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibUnsubscribe"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_unsubscribe"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_unsubscribe"
app:layout_constraintStart_toEndOf="@+id/ibAnswer"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_unsubscribe_24" />
app:srcCompat="@drawable/baseline_unsubscribe_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibUndo"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_undo"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_undo"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@+id/ibImages"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_undo_24" />
app:srcCompat="@drawable/baseline_undo_24"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/ibImages"
android:id="@+id/ibVerify"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_images"
android:contentDescription="@string/title_sign"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_images"
app:layout_constraintEnd_toStartOf="@+id/ibFull"
android:tooltipText="@string/title_sign"
app:layout_constraintEnd_toStartOf="@+id/ibDecrypt"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_image_24" />
app:srcCompat="@drawable/baseline_gesture_24" />
<ImageButton
android:id="@+id/ibFull"
android:id="@+id/ibDecrypt"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_legend_show_full"
android:contentDescription="@string/title_decrypt"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="3dp"
android:padding="6dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_legend_show_full"
app:layout_constraintEnd_toEndOf="parent"
android:tooltipText="@string/title_decrypt"
app:layout_constraintEnd_toStartOf="@+id/ibImages"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_fullscreen_24" />
app:srcCompat="@drawable/baseline_lock_open_24" />
<ImageButton
android:id="@+id/ibVerify"
android:id="@+id/ibImages"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_sign"
android:contentDescription="@string/title_legend_show_images"
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" />
android:tooltipText="@string/title_legend_show_images"
app:layout_constraintEnd_toStartOf="@+id/ibFull"
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_image_24" />
<ImageButton
android:id="@+id/ibDecrypt"
android:id="@+id/ibFull"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/title_decrypt"
android:contentDescription="@string/title_legend_show_full"
android:foregroundTint="?android:attr/textColorSecondary"
android:padding="6dp"
android:padding="3dp"
android:scaleType="fitCenter"
android:tooltipText="@string/title_decrypt"
android:tooltipText="@string/title_legend_show_full"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibFull"
app:srcCompat="@drawable/baseline_lock_open_24" />
app:layout_constraintTop_toBottomOf="@id/vSeparator"
app:srcCompat="@drawable/baseline_fullscreen_24" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvSignedData"
@ -226,16 +209,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibVerify" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvCrossHint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:text="@string/title_message_bar_hint"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/ibRemove"
app:layout_constraintTop_toBottomOf="@id/tvSignedData" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -744,7 +744,6 @@
<string name="title_ask_help">Help improve FairEmail</string>
<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_ask_review">Please review FairEmail</string>
<string name="title_ask_review_rationale">

Loading…
Cancel
Save