diff --git a/app/src/main/java/eu/faircode/email/FragmentMessage.java b/app/src/main/java/eu/faircode/email/FragmentMessage.java
deleted file mode 100644
index fe7b2a53..00000000
--- a/app/src/main/java/eu/faircode/email/FragmentMessage.java
+++ /dev/null
@@ -1,1387 +0,0 @@
-package eu.faircode.email;
-
-/*
- This file is part of FairEmail.
-
- FairEmail is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- NetGuard is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with NetGuard. If not, see .
-
- Copyright 2018 by Marcel Bokhorst (M66B)
-*/
-
-import android.Manifest;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.ContactsContract;
-import android.text.Editable;
-import android.text.Html;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextUtils;
-import android.text.method.LinkMovementMethod;
-import android.text.style.ImageSpan;
-import android.text.style.URLSpan;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.google.android.material.bottomnavigation.BottomNavigationView;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-
-import org.xml.sax.XMLReader;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.text.Collator;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import javax.mail.Address;
-import javax.mail.internet.InternetAddress;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.PopupMenu;
-import androidx.constraintlayout.widget.Group;
-import androidx.core.content.ContextCompat;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.lifecycle.Observer;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-public class FragmentMessage extends FragmentEx {
- private ViewGroup view;
- private View vwAnswerAnchor;
- private ImageView ivFlagged;
- private ImageView ivAvatar;
- private TextView tvFrom;
- private ImageView ivContactAdd;
- private TextView tvTime;
- private TextView tvCount;
- private TextView tvTo;
- private TextView tvSubject;
- private TextView tvReplyTo;
- private TextView tvCc;
- private TextView tvBcc;
- private TextView tvRawHeaders;
- private ProgressBar pbRawHeaders;
- private RecyclerView rvAttachment;
- private TextView tvError;
- private View vSeparatorBody;
- private Button btnImages;
- private TextView tvBody;
- private ProgressBar pbBody;
- private FloatingActionButton fab;
- private BottomNavigationView bottom_navigation;
- private ProgressBar pbWait;
- private Group grpHeader;
- private Group grpThread;
- private Group grpAddresses;
- private Group grpRawHeaders;
- private Group grpAttachments;
- private Group grpError;
- private Group grpMessage;
-
- private TupleMessageEx message = null;
- private boolean free = false;
- private boolean addresses = false;
- private boolean show_images = false;
- private boolean headers = false;
- private AdapterAttachment adapter;
-
- private boolean debug;
- private DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-
- private static final long CACHE_IMAGE_DURATION = 3 * 24 * 3600 * 1000L;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (savedInstanceState == null)
- message = (TupleMessageEx) getArguments().getSerializable("message");
- else
- message = (TupleMessageEx) savedInstanceState.getSerializable("message");
- }
-
- @Override
- @Nullable
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- view = (ViewGroup) inflater.inflate(R.layout.fragment_message, container, false);
-
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
- debug = prefs.getBoolean("debug", false);
-
- // Get controls
- vwAnswerAnchor = view.findViewById(R.id.vwAnswerAnchor);
- ivFlagged = view.findViewById(R.id.ivFlagged);
- ivAvatar = view.findViewById(R.id.ivAvatar);
- tvFrom = view.findViewById(R.id.tvFrom);
- ivContactAdd = view.findViewById(R.id.ivAddContact);
- tvTime = view.findViewById(R.id.tvTime);
- tvCount = view.findViewById(R.id.tvCount);
- tvTo = view.findViewById(R.id.tvTo);
- tvSubject = view.findViewById(R.id.tvSubject);
- tvReplyTo = view.findViewById(R.id.tvReplyTo);
- tvCc = view.findViewById(R.id.tvCc);
- tvBcc = view.findViewById(R.id.tvBcc);
- tvRawHeaders = view.findViewById(R.id.tvRawHeaders);
- pbRawHeaders = view.findViewById(R.id.pbRawHeaders);
- rvAttachment = view.findViewById(R.id.rvAttachment);
- tvError = view.findViewById(R.id.tvError);
- vSeparatorBody = view.findViewById(R.id.vSeparatorBody);
- btnImages = view.findViewById(R.id.btnImages);
- tvBody = view.findViewById(R.id.tvBody);
- pbBody = view.findViewById(R.id.pbBody);
- fab = view.findViewById(R.id.fab);
- bottom_navigation = view.findViewById(R.id.bottom_navigation);
- pbWait = view.findViewById(R.id.pbWait);
- grpHeader = view.findViewById(R.id.grpHeader);
- grpThread = view.findViewById(R.id.grpThread);
- grpAddresses = view.findViewById(R.id.grpAddresses);
- grpRawHeaders = view.findViewById(R.id.grpRawHeaders);
- grpAttachments = view.findViewById(R.id.grpAttachments);
- grpError = view.findViewById(R.id.grpError);
- grpMessage = view.findViewById(R.id.grpMessage);
-
- setHasOptionsMenu(true);
-
- ivFlagged.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
- args.putBoolean("flagged", !message.ui_flagged);
- Log.i(Helper.TAG, "Set message id=" + message.id + " flagged=" + !message.ui_flagged);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) throws Throwable {
- long id = args.getLong("id");
- boolean flagged = args.getBoolean("flagged");
- DB db = DB.getInstance(context);
- EntityMessage message = db.message().getMessage(id);
- db.message().setMessageUiFlagged(message.id, flagged);
- EntityOperation.queue(db, message, EntityOperation.FLAG, flagged);
- EntityOperation.process(context);
- return null;
- }
- }.load(FragmentMessage.this, args);
- }
- });
-
- ivContactAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- for (Address address : message.from) {
- InternetAddress ia = (InternetAddress) address;
- String name = ia.getPersonal();
- String email = ia.getAddress();
-
- // https://developer.android.com/training/contacts-provider/modify-data
- Intent edit = new Intent();
- if (!TextUtils.isEmpty(name))
- edit.putExtra(ContactsContract.Intents.Insert.NAME, name);
- if (!TextUtils.isEmpty(email))
- edit.putExtra(ContactsContract.Intents.Insert.EMAIL, email);
-
- Cursor cursor = null;
- try {
- ContentResolver resolver = getContext().getContentResolver();
- cursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
- new String[]{
- ContactsContract.CommonDataKinds.Photo.CONTACT_ID,
- ContactsContract.Contacts.LOOKUP_KEY
- },
- ContactsContract.CommonDataKinds.Email.ADDRESS + " = ?",
- new String[]{email}, null);
- if (cursor.moveToNext()) {
- int colContactId = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID);
- int colLookupKey = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
-
- long contactId = cursor.getLong(colContactId);
- String lookupKey = cursor.getString(colLookupKey);
-
- Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
-
- edit.setAction(Intent.ACTION_EDIT);
- edit.setDataAndType(lookupUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
- } else {
- edit.setAction(Intent.ACTION_INSERT);
- edit.setType(ContactsContract.Contacts.CONTENT_TYPE);
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
- startActivity(edit);
- }
- }
- });
-
- btnImages.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- btnImages.setEnabled(false);
- show_images = true;
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
- args.putBoolean("show_images", show_images);
- bodyTask.load(FragmentMessage.this, args);
- }
- });
-
- tvBody.setMovementMethod(new LinkMovementMethod() {
- public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
- if (event.getAction() != MotionEvent.ACTION_UP)
- return false;
-
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- x -= widget.getTotalPaddingLeft();
- y -= widget.getTotalPaddingTop();
-
- x += widget.getScrollX();
- y += widget.getScrollY();
-
- Layout layout = widget.getLayout();
- int line = layout.getLineForVertical(y);
- int off = layout.getOffsetForHorizontal(line, x);
-
- URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
- if (link.length != 0) {
- String url = link[0].getURL();
- Uri uri = Uri.parse(url);
-
- if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
- Toast.makeText(getContext(), getString(R.string.title_no_viewer, uri.toString()), Toast.LENGTH_LONG).show();
- return true;
- }
-
- if (BuildConfig.APPLICATION_ID.equals(uri.getHost()) && "/activate/".equals(uri.getPath())) {
- LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
- lbm.sendBroadcast(
- new Intent(ActivityView.ACTION_ACTIVATE_PRO)
- .putExtra("uri", uri));
-
- } else {
- View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_link, null);
- final EditText etLink = view.findViewById(R.id.etLink);
- etLink.setText(url);
- new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
- .setView(view)
- .setPositiveButton(R.string.title_yes, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Uri uri = Uri.parse(etLink.getText().toString());
-
- if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
- Toast.makeText(getContext(), getString(R.string.title_no_viewer, uri.toString()), Toast.LENGTH_LONG).show();
- return;
- }
-
- Helper.view(getContext(), uri);
- }
- })
- .setNegativeButton(R.string.title_no, null)
- .show();
- }
- }
-
- return true;
- }
- });
-
- // Wire controls
-
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- free = true;
-
- getActivity().invalidateOptionsMenu();
-
- grpHeader.setVisibility(View.GONE);
- vSeparatorBody.setVisibility(View.GONE);
- fab.hide();
-
- grpThread.setVisibility(View.GONE);
- grpAddresses.setVisibility(View.GONE);
- pbRawHeaders.setVisibility(View.GONE);
- grpRawHeaders.setVisibility(View.GONE);
- grpAttachments.setVisibility(View.GONE);
- grpError.setVisibility(View.GONE);
-
- setTextSize();
- }
- });
-
- ((ActivityBase) getActivity()).addBackPressedListener(new ActivityBase.IBackPressedListener() {
- @Override
- public boolean onBackPressed() {
- if (free && isVisible()) {
- free = false;
-
- getActivity().invalidateOptionsMenu();
-
- grpHeader.setVisibility(View.VISIBLE);
- vSeparatorBody.setVisibility(View.VISIBLE);
- fab.show();
-
- RecyclerView.Adapter adapter = rvAttachment.getAdapter();
-
- grpThread.setVisibility(View.VISIBLE);
- grpAddresses.setVisibility(addresses ? View.VISIBLE : View.GONE);
- pbRawHeaders.setVisibility(headers && message.headers == null ? View.VISIBLE : View.GONE);
- grpRawHeaders.setVisibility(headers ? View.VISIBLE : View.GONE);
- grpAttachments.setVisibility(adapter != null && adapter.getItemCount() > 0 ? View.VISIBLE : View.GONE);
-
- setTextSize();
-
- return true;
- }
- return false;
- }
- });
-
- bottom_navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
- @Override
- public boolean onNavigationItemSelected(@NonNull MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_spam:
- onActionSpam();
- return true;
- case R.id.action_delete:
- onActionDelete();
- return true;
- case R.id.action_move:
- onActionMove();
- return true;
- case R.id.action_archive:
- onActionArchive();
- return true;
- case R.id.action_reply:
- onActionReply();
- return true;
- }
- return false;
- }
- });
-
- // Initialize
- grpHeader.setVisibility(View.GONE);
- grpAddresses.setVisibility(View.GONE);
- pbRawHeaders.setVisibility(View.GONE);
- grpRawHeaders.setVisibility(View.GONE);
- grpAttachments.setVisibility(View.GONE);
- btnImages.setVisibility(View.GONE);
- grpMessage.setVisibility(View.GONE);
- pbBody.setVisibility(View.GONE);
- bottom_navigation.setVisibility(View.GONE);
- grpThread.setVisibility(View.GONE);
- grpError.setVisibility(View.GONE);
- fab.hide();
- pbWait.setVisibility(View.VISIBLE);
-
- rvAttachment.setHasFixedSize(false);
- LinearLayoutManager llm = new LinearLayoutManager(getContext());
- rvAttachment.setLayoutManager(llm);
- rvAttachment.setItemAnimator(null);
-
- adapter = new AdapterAttachment(getContext(), getViewLifecycleOwner(), true);
- rvAttachment.setAdapter(adapter);
-
- return view;
- }
-
- @Override
- public void onDestroyView() {
- adapter = null;
- super.onDestroyView();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putSerializable("message", message);
- outState.putBoolean("free", free);
- outState.putBoolean("headers", headers);
- outState.putBoolean("addresses", addresses);
- outState.putBoolean("show_images", show_images);
- }
-
- @Override
- public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- if (savedInstanceState == null) {
- String name = (message.folderDisplay == null
- ? Helper.localizeFolderName(getContext(), message.folderName)
- : message.folderDisplay);
- setSubtitle(name);
-
- ivFlagged.setImageResource(message.ui_flagged ? R.drawable.baseline_star_24 : R.drawable.baseline_star_border_24);
- tvFrom.setText(MessageHelper.getFormattedAddresses(message.from, true));
- tvTime.setText(message.sent == null ? null : df.format(new Date(message.sent)));
- tvCount.setText(Integer.toString(message.count));
- tvTo.setText(MessageHelper.getFormattedAddresses(message.to, true));
- tvSubject.setText(message.subject);
-
- tvReplyTo.setText(MessageHelper.getFormattedAddresses(message.reply, true));
- tvCc.setText(MessageHelper.getFormattedAddresses(message.cc, true));
- tvBcc.setText(MessageHelper.getFormattedAddresses(message.bcc, true));
-
- tvRawHeaders.setText(message.headers);
-
- tvError.setText(message.error);
- } else {
- free = savedInstanceState.getBoolean("free");
- headers = savedInstanceState.getBoolean("headers");
- addresses = savedInstanceState.getBoolean("addresses");
- show_images = savedInstanceState.getBoolean("show_images");
- }
-
- setSeen();
-
- boolean photo = false;
- if (message.avatar != null &&
- ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CONTACTS)
- == PackageManager.PERMISSION_GRANTED) {
- ContentResolver resolver = getContext().getContentResolver();
- InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(resolver, Uri.parse(message.avatar));
- if (is != null) {
- photo = true;
- ivAvatar.setImageDrawable(Drawable.createFromStream(is, "avatar"));
- }
- }
- if (!photo) {
- ViewGroup.LayoutParams lp = ivAvatar.getLayoutParams();
- lp.height = 0;
- lp.width = 0;
- ivAvatar.setLayoutParams(lp);
- }
-
- if (message.from == null ||
- ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- ViewGroup.LayoutParams lp = ivContactAdd.getLayoutParams();
- lp.height = 0;
- lp.width = 0;
- ivContactAdd.setLayoutParams(lp);
- }
-
- pbBody.setVisibility(View.VISIBLE);
-
- pbWait.setVisibility(View.GONE);
-
- grpHeader.setVisibility(free ? View.GONE : View.VISIBLE);
- vSeparatorBody.setVisibility(free ? View.GONE : View.VISIBLE);
-
- grpAddresses.setVisibility(!free && addresses ? View.VISIBLE : View.GONE);
- grpThread.setVisibility(free ? View.GONE : View.VISIBLE);
- pbRawHeaders.setVisibility(!free && headers && message.headers == null ? View.VISIBLE : View.GONE);
- grpRawHeaders.setVisibility(free || !headers ? View.GONE : View.VISIBLE);
- grpError.setVisibility(message.error == null ? View.GONE : View.VISIBLE);
-
- final DB db = DB.getInstance(getContext());
-
- // Observe message
- db.message().liveMessage(message.id).observe(getViewLifecycleOwner(), new Observer() {
- private boolean loaded = false;
- private boolean observing = false;
-
- @Override
- public void onChanged(@Nullable final TupleMessageEx message) {
- if (message == null || (!(debug && BuildConfig.DEBUG) && message.ui_hide)) {
- // Message gone (moved, deleted)
- finish();
- return;
- }
-
- // Messages are immutable except for flags
- FragmentMessage.this.message = message;
- setSeen();
- ivFlagged.setImageResource(message.ui_flagged ? R.drawable.baseline_star_24 : R.drawable.baseline_star_border_24);
-
- // Headers can be downloaded
- tvRawHeaders.setText(message.headers);
- pbRawHeaders.setVisibility(!free && headers && message.headers == null ? View.VISIBLE : View.GONE);
-
- // Body can be downloaded
- if (!loaded && message.content) {
- loaded = true;
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
- args.putBoolean("show_images", show_images);
-
- pbBody.setVisibility(View.VISIBLE);
-
- bodyTask.load(FragmentMessage.this, args);
- }
-
- // Message count can be changed
- getActivity().invalidateOptionsMenu();
-
- // Messages can be moved to another folder
- String name = (message.folderDisplay == null
- ? Helper.localizeFolderName(getContext(), message.folderName)
- : message.folderDisplay);
- setSubtitle(name);
-
- // Observe folders
- if (observing)
- return;
- observing = true;
- db.folder().liveFolders(message.account).observe(getViewLifecycleOwner(), new Observer>() {
- @Override
- public void onChanged(@Nullable List folders) {
- boolean hasTrash = false;
- boolean hasJunk = false;
- boolean hasArchive = false;
- boolean hasUser = false;
-
- if (folders != null)
- for (EntityFolder folder : folders) {
- if (EntityFolder.TRASH.equals(folder.type))
- hasTrash = true;
- else if (EntityFolder.JUNK.equals(folder.type))
- hasJunk = true;
- else if (EntityFolder.ARCHIVE.equals(folder.type))
- hasArchive = true;
- else if (EntityFolder.USER.equals(folder.type))
- hasUser = true;
- }
-
- boolean inInbox = EntityFolder.INBOX.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 inJunk = EntityFolder.JUNK.equals(message.folderType);
-
- bottom_navigation.setTag(inTrash || !hasTrash || inOutbox);
-
- bottom_navigation.getMenu().findItem(R.id.action_spam).setVisible(message.uid != null && !inArchive && !inJunk && hasJunk);
- bottom_navigation.getMenu().findItem(R.id.action_delete).setVisible((message.uid != null && hasTrash) || (inOutbox && !TextUtils.isEmpty(message.error)));
- bottom_navigation.getMenu().findItem(R.id.action_move).setVisible(message.uid != null && (!inInbox || hasUser));
- bottom_navigation.getMenu().findItem(R.id.action_archive).setVisible(message.uid != null && !inArchive && hasArchive);
- bottom_navigation.getMenu().findItem(R.id.action_reply).setVisible(message.content && !inOutbox);
- bottom_navigation.setVisibility(View.VISIBLE);
- }
- });
- }
- });
-
- // Observe attachments
- db.attachment().liveAttachments(message.id).observe(getViewLifecycleOwner(),
- new Observer>() {
- @Override
- public void onChanged(@Nullable List attachments) {
- if (attachments == null)
- attachments = new ArrayList<>();
-
- adapter.set(attachments);
- grpAttachments.setVisibility(!free && attachments.size() > 0 ? View.VISIBLE : View.GONE);
-
- if (message.content) {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
- args.putBoolean("show_images", show_images);
-
- pbBody.setVisibility(View.VISIBLE);
-
- bodyTask.load(FragmentMessage.this, args);
- }
- }
- });
-
- }
-
- private void setSeen() {
- int typeface = (message.ui_seen ? Typeface.NORMAL : Typeface.BOLD);
- tvFrom.setTypeface(null, typeface);
- tvTime.setTypeface(null, typeface);
- tvSubject.setTypeface(null, typeface);
- tvCount.setTypeface(null, typeface);
-
- int colorUnseen = Helper.resolveColor(getContext(), message.ui_seen
- ? android.R.attr.textColorSecondary : R.attr.colorUnread);
- tvFrom.setTextColor(colorUnseen);
- tvTime.setTextColor(colorUnseen);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.menu_view, menu);
- super.onCreateOptionsMenu(menu, inflater);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
-
- boolean inOutbox = EntityFolder.OUTBOX.equals(message.folderType);
-
- menu.findItem(R.id.menu_addresses).setVisible(!free);
- menu.findItem(R.id.menu_text_size).setVisible(free);
- menu.findItem(R.id.menu_thread).setVisible(message.count > 1);
- menu.findItem(R.id.menu_forward).setVisible(message.content && !inOutbox);
- menu.findItem(R.id.menu_show_headers).setChecked(headers);
- menu.findItem(R.id.menu_show_headers).setEnabled(message.uid != null);
- menu.findItem(R.id.menu_show_headers).setVisible(!free);
- menu.findItem(R.id.menu_show_html).setEnabled(message.content && Helper.classExists("android.webkit.WebView"));
- menu.findItem(R.id.menu_reply_all).setVisible(message.content && !inOutbox);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_addresses:
- onMenuAddresses();
- return true;
- case R.id.menu_text_size:
- onMenuTextSize();
- return true;
- case R.id.menu_thread:
- onMenuThread();
- return true;
- case R.id.menu_forward:
- onMenuForward();
- return true;
- case R.id.menu_reply_all:
- onMenuReplyAll();
- return true;
- case R.id.menu_show_html:
- onMenuShowHtml();
- return true;
- case R.id.menu_show_headers:
- onMenuShowHeaders();
- return true;
- case R.id.menu_unseen:
- onMenuUnseen();
- return true;
- case R.id.menu_answer:
- onMenuAnswer();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void onMenuAddresses() {
- addresses = !addresses;
- grpAddresses.setVisibility(addresses ? View.VISIBLE : View.GONE);
- }
-
- private void onMenuTextSize() {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
- int size = prefs.getInt("size", 0);
- size = ++size % 3;
- prefs.edit().putInt("size", size).apply();
-
- setTextSize();
- }
-
- private void onMenuThread() {
- getFragmentManager().popBackStack("thread", FragmentManager.POP_BACK_STACK_INCLUSIVE);
-
- Bundle args = new Bundle();
- args.putLong("thread", message.id);
-
- FragmentMessages fragment = new FragmentMessages();
- fragment.setArguments(args);
-
- FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
- fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("thread");
- fragmentTransaction.commit();
- }
-
- private void onMenuForward() {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Boolean onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
- List attachments = DB.getInstance(context).attachment().getAttachments(id);
- for (EntityAttachment attachment : attachments)
- if (!attachment.available)
- return false;
- return true;
- }
-
- @Override
- protected void onLoaded(Bundle args, Boolean available) {
- final Intent forward = new Intent(getContext(), ActivityCompose.class)
- .putExtra("action", "forward")
- .putExtra("reference", message.id);
- if (available)
- startActivity(forward);
- else
- new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
- .setMessage(R.string.title_attachment_unavailable)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- startActivity(forward);
- }
- })
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- }
- }.load(this, args);
- }
-
- private void onMenuReplyAll() {
- startActivity(new Intent(getContext(), ActivityCompose.class)
- .putExtra("action", "reply_all")
- .putExtra("reference", message.id));
- }
-
- private void onMenuShowHeaders() {
- headers = !headers;
- getActivity().invalidateOptionsMenu();
- pbRawHeaders.setVisibility(headers && message.headers == null ? View.VISIBLE : View.GONE);
- grpRawHeaders.setVisibility(headers ? View.VISIBLE : View.GONE);
-
- if (headers && message.headers == null) {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) {
- Long id = args.getLong("id");
- DB db = DB.getInstance(context);
- EntityMessage message = db.message().getMessage(id);
- EntityOperation.queue(db, message, EntityOperation.HEADERS);
- EntityOperation.process(context);
- return null;
- }
- }.load(this, args);
- }
- }
-
- private void onMenuShowHtml() {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
- args.putString("from", MessageHelper.getFormattedAddresses(message.from, true));
-
- FragmentWebView fragment = new FragmentWebView();
- fragment.setArguments(args);
-
- FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
- fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("webview");
- fragmentTransaction.commit();
- }
-
- private void onMenuUnseen() {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) throws Throwable {
- long id = args.getLong("id");
-
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- EntityMessage message = db.message().getMessage(id);
- db.message().setMessageUiSeen(message.id, false);
- EntityOperation.queue(db, message, EntityOperation.SEEN, true);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return null;
- }
-
- @Override
- protected void onLoaded(Bundle args, Void data) {
- finish();
- }
- }.load(this, args);
- }
-
- private void onMenuAnswer() {
- DB.getInstance(getContext()).answer().liveAnswers().observe(getViewLifecycleOwner(), new Observer>() {
- @Override
- public void onChanged(List answers) {
- final Collator collator = Collator.getInstance(Locale.getDefault());
- collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
-
- Collections.sort(answers, new Comparator() {
- @Override
- public int compare(EntityAnswer a1, EntityAnswer a2) {
- return collator.compare(a1.name, a2.name);
- }
- });
-
- PopupMenu popupMenu = new PopupMenu(getContext(), vwAnswerAnchor);
-
- int order = 0;
- for (EntityAnswer answer : answers)
- popupMenu.getMenu().add(Menu.NONE, answer.id.intValue(), order++, answer.name);
-
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem target) {
- if (Helper.isPro(getContext())) {
- startActivity(new Intent(getContext(), ActivityCompose.class)
- .putExtra("action", "reply")
- .putExtra("reference", message.id)
- .putExtra("answer", (long) target.getItemId()));
- } else {
- FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
- fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
- fragmentTransaction.commit();
- }
- return true;
- }
- });
-
- popupMenu.show();
- }
- });
- }
-
- private void onActionSpam() {
- new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
- .setMessage(R.string.title_ask_spam)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Helper.setViewsEnabled(view, false);
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
-
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- db.message().setMessageUiHide(id, true);
-
- EntityMessage message = db.message().getMessage(id);
- EntityFolder spam = db.folder().getFolderByType(message.account, EntityFolder.JUNK);
- EntityOperation.queue(db, message, EntityOperation.MOVE, spam.id);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return null;
- }
-
- @Override
- protected void onLoaded(Bundle args, Void result) {
- Helper.setViewsEnabled(view, true);
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- Helper.setViewsEnabled(view, true);
- Helper.unexpectedError(getContext(), ex);
- }
- }.load(FragmentMessage.this, args);
- }
- })
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- }
-
- private void onActionDelete() {
- boolean delete = (Boolean) bottom_navigation.getTag();
- if (delete) {
- // No trash or is trash
- new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
- .setMessage(R.string.title_ask_delete)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Helper.setViewsEnabled(view, false);
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
-
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- EntityMessage message = db.message().getMessage(id);
- if (message.uid == null && !TextUtils.isEmpty(message.error)) // outbox
- db.message().deleteMessage(id);
- else {
- db.message().setMessageUiHide(message.id, true);
- EntityOperation.queue(db, message, EntityOperation.DELETE);
- }
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return null;
- }
-
- @Override
- protected void onLoaded(Bundle args, Void result) {
- Helper.setViewsEnabled(view, true);
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- Helper.setViewsEnabled(view, true);
- Helper.unexpectedError(getContext(), ex);
- }
- }.load(FragmentMessage.this, args);
- }
- })
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- } else {
- Helper.setViewsEnabled(view, false);
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- db.message().setMessageUiHide(id, true);
-
- EntityMessage message = db.message().getMessage(id);
- EntityFolder trash = db.folder().getFolderByType(message.account, EntityFolder.TRASH);
- EntityOperation.queue(db, message, EntityOperation.MOVE, trash.id);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return null;
- }
-
- @Override
- protected void onLoaded(Bundle args, Void result) {
- Helper.setViewsEnabled(view, true);
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- Helper.setViewsEnabled(view, true);
- Helper.unexpectedError(getContext(), ex);
- }
- }.load(FragmentMessage.this, args);
- }
- }
-
- private void onActionMove() {
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask>() {
- @Override
- protected List onLoad(Context context, Bundle args) {
- EntityMessage message;
- List folders;
-
- DB db = DB.getInstance(getContext());
- try {
- db.beginTransaction();
-
- message = db.message().getMessage(args.getLong("id"));
- folders = db.folder().getUserFolders(message.account);
-
- for (int i = 0; i < folders.size(); i++)
- if (folders.get(i).id.equals(message.folder)) {
- folders.remove(i);
- break;
- }
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- final Collator collator = Collator.getInstance(Locale.getDefault());
- collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
-
- Collections.sort(folders, new Comparator() {
- @Override
- public int compare(EntityFolder f1, EntityFolder f2) {
- return collator.compare(f1.name, f2.name);
- }
- });
-
- EntityFolder sent = db.folder().getFolderByType(message.account, EntityFolder.SENT);
- if (!message.folder.equals(sent.id))
- folders.add(0, sent);
-
- EntityFolder inbox = db.folder().getFolderByType(message.account, EntityFolder.INBOX);
- if (!message.folder.equals(inbox.id))
- folders.add(0, inbox);
-
- return folders;
- }
-
- @Override
- protected void onLoaded(final Bundle args, List folders) {
- View anchor = bottom_navigation.findViewById(R.id.action_move);
- PopupMenu popupMenu = new PopupMenu(getContext(), anchor);
-
- int order = 0;
- for (EntityFolder folder : folders) {
- String name = (folder.display == null
- ? Helper.localizeFolderName(getContext(), folder.name)
- : folder.display);
- popupMenu.getMenu().add(Menu.NONE, folder.id.intValue(), order++, name);
- }
-
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(final MenuItem target) {
- Helper.setViewsEnabled(view, false);
-
- args.putLong("target", target.getItemId());
-
- new SimpleTask() {
- @Override
- protected Boolean onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
- long target = args.getLong("target");
-
- boolean close;
-
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- EntityMessage message = db.message().getMessage(id);
- EntityFolder folder = db.folder().getFolder(message.folder);
-
- close = EntityFolder.ARCHIVE.equals(folder.type);
- if (!close)
- db.message().setMessageUiHide(message.id, true);
-
- EntityOperation.queue(db, message, EntityOperation.MOVE, target);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return close;
- }
-
- @Override
- protected void onLoaded(Bundle args, Boolean close) {
- Helper.setViewsEnabled(view, true);
- if (close) // archived message
- getFragmentManager().popBackStack();
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- Helper.setViewsEnabled(view, true);
- Helper.unexpectedError(getContext(), ex);
- }
- }.load(FragmentMessage.this, args);
-
- return true;
- }
- });
-
- popupMenu.show();
- }
- }.load(FragmentMessage.this, args);
- }
-
- private void onActionArchive() {
- Helper.setViewsEnabled(view, false);
-
- Bundle args = new Bundle();
- args.putLong("id", message.id);
-
- new SimpleTask() {
- @Override
- protected Void onLoad(Context context, Bundle args) {
- long id = args.getLong("id");
-
- DB db = DB.getInstance(context);
- try {
- db.beginTransaction();
-
- db.message().setMessageUiHide(id, true);
-
- EntityMessage message = db.message().getMessage(id);
- EntityFolder archive = db.folder().getFolderByType(message.account, EntityFolder.ARCHIVE);
- EntityOperation.queue(db, message, EntityOperation.MOVE, archive.id);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
-
- EntityOperation.process(context);
-
- return null;
- }
-
- @Override
- protected void onLoaded(Bundle args, Void result) {
- getFragmentManager().popBackStack();
- Helper.setViewsEnabled(view, true);
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- Helper.setViewsEnabled(view, true);
- Helper.unexpectedError(getContext(), ex);
- }
- }.load(FragmentMessage.this, args);
- }
-
- private void onActionReply() {
- startActivity(new Intent(getContext(), ActivityCompose.class)
- .putExtra("action", "reply")
- .putExtra("reference", message.id));
- }
-
- private SimpleTask bodyTask = new SimpleTask() {
- @Override
- protected Spanned onLoad(final Context context, final Bundle args) throws Throwable {
- final long id = args.getLong("id");
- final boolean show_images = args.getBoolean("show_images");
- String body = message.read(context);
- args.putInt("size", body.length());
- return decodeHtml(context, id, body, show_images);
- }
-
- @Override
- protected void onLoaded(Bundle args, Spanned body) {
- boolean show_images = args.getBoolean("show_images");
-
- SpannedString ss = new SpannedString(body);
- boolean has_images = (ss.getSpans(0, ss.length(), ImageSpan.class).length > 0);
-
- setTextSize();
- tvBody.setText(body);
- btnImages.setVisibility(has_images && !show_images ? View.VISIBLE : View.GONE);
- grpMessage.setVisibility(View.VISIBLE);
- if (free)
- fab.hide();
- else
- fab.show();
- pbBody.setVisibility(View.GONE);
- }
- };
-
- private static Spanned decodeHtml(final Context context, final long id, String body, final boolean show_images) {
- return Html.fromHtml(HtmlHelper.sanitize(body), new Html.ImageGetter() {
- @Override
- public Drawable getDrawable(String source) {
- float scale = context.getResources().getDisplayMetrics().density;
- int px = (int) (24 * scale + 0.5f);
-
- if (source != null && source.startsWith("cid")) {
- String cid = "<" + source.split(":")[1] + ">";
- EntityAttachment attachment = DB.getInstance(context).attachment().getAttachment(id, cid);
- if (attachment == null || !attachment.available) {
- Drawable d = context.getResources().getDrawable(R.drawable.baseline_warning_24, context.getTheme());
- d.setBounds(0, 0, px, px);
- return d;
- } else {
- File file = EntityAttachment.getFile(context, attachment.id);
- Drawable d = Drawable.createFromPath(file.getAbsolutePath());
- d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
- return d;
- }
- }
-
- if (show_images) {
- // Get cache folder
- File dir = new File(context.getCacheDir(), "images");
- dir.mkdir();
-
- // Cleanup cache
- long now = new Date().getTime();
- File[] images = dir.listFiles();
- if (images != null)
- for (File image : images)
- if (image.isFile() && image.lastModified() + CACHE_IMAGE_DURATION < now) {
- Log.i(Helper.TAG, "Deleting from image cache " + image.getName());
- image.delete();
- }
-
- InputStream is = null;
- FileOutputStream os = null;
- try {
- if (source == null)
- throw new IllegalArgumentException("Html.ImageGetter.getDrawable(source == null)");
-
- // Create unique file name
- File file = new File(dir, id + "_" + source.hashCode());
-
- // Get input stream
- if (file.exists()) {
- Log.i(Helper.TAG, "Using cached " + file);
- is = new FileInputStream(file);
- } else {
- Log.i(Helper.TAG, "Downloading " + source);
- is = new URL(source).openStream();
- }
-
- // Decode image from stream
- Bitmap bm = BitmapFactory.decodeStream(is);
- if (bm == null)
- throw new IllegalArgumentException();
-
- // Cache bitmap
- if (!file.exists()) {
- os = new FileOutputStream(file);
- bm.compress(Bitmap.CompressFormat.PNG, 100, os);
- }
-
- // Create drawable from bitmap
- Drawable d = new BitmapDrawable(context.getResources(), bm);
- d.setBounds(0, 0, bm.getWidth(), bm.getHeight());
- return d;
- } catch (Throwable ex) {
- // Show warning icon
- Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
- Drawable d = context.getResources().getDrawable(R.drawable.baseline_warning_24, context.getTheme());
- d.setBounds(0, 0, px, px);
- return d;
- } finally {
- // Close streams
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- Log.w(Helper.TAG, e + "\n" + Log.getStackTraceString(e));
- }
- }
- if (os != null) {
- try {
- os.close();
- } catch (IOException e) {
- Log.w(Helper.TAG, e + "\n" + Log.getStackTraceString(e));
- }
- }
- }
- } else {
- // Show placeholder icon
- Drawable d = context.getResources().getDrawable(R.drawable.baseline_image_24, context.getTheme());
- d.setBounds(0, 0, px, px);
- return d;
- }
- }
- }, new Html.TagHandler() {
- @Override
- public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
- Log.i(Helper.TAG, "HTML tag=" + tag + " opening=" + opening);
- }
- });
- }
-
- private void setTextSize() {
- int style = R.style.TextAppearance_AppCompat_Small;
-
- if (free) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
- int size = prefs.getInt("size", 0);
- if (size == 1)
- style = R.style.TextAppearance_AppCompat_Medium;
- else if (size == 2)
- style = R.style.TextAppearance_AppCompat_Large;
- }
-
- TypedArray ta = getContext().obtainStyledAttributes(style, new int[]{android.R.attr.textSize});
- tvBody.setTextSize(TypedValue.COMPLEX_UNIT_PX, ta.getDimensionPixelSize(0, 0));
- }
-}
diff --git a/app/src/main/res/drawable/baseline_format_size_24.xml b/app/src/main/res/drawable/baseline_format_size_24.xml
deleted file mode 100644
index 754c1127..00000000
--- a/app/src/main/res/drawable/baseline_format_size_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_fullscreen_24.xml b/app/src/main/res/drawable/baseline_fullscreen_24.xml
deleted file mode 100755
index 48e3c310..00000000
--- a/app/src/main/res/drawable/baseline_fullscreen_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_fullscreen_exit_24.xml b/app/src/main/res/drawable/baseline_fullscreen_exit_24.xml
deleted file mode 100755
index 01b8d4f4..00000000
--- a/app/src/main/res/drawable/baseline_fullscreen_exit_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_inbox_24.xml b/app/src/main/res/drawable/baseline_inbox_24.xml
deleted file mode 100644
index eddf19ea..00000000
--- a/app/src/main/res/drawable/baseline_inbox_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_more_horiz_24.xml b/app/src/main/res/drawable/baseline_more_horiz_24.xml
deleted file mode 100644
index eba29c35..00000000
--- a/app/src/main/res/drawable/baseline_more_horiz_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_report_24.xml b/app/src/main/res/drawable/baseline_report_24.xml
deleted file mode 100755
index d8544cb9..00000000
--- a/app/src/main/res/drawable/baseline_report_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_unarchive_24.xml b/app/src/main/res/drawable/baseline_unarchive_24.xml
deleted file mode 100755
index 635073ff..00000000
--- a/app/src/main/res/drawable/baseline_unarchive_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/baseline_visibility_off_24.xml b/app/src/main/res/drawable/baseline_visibility_off_24.xml
deleted file mode 100755
index a902321e..00000000
--- a/app/src/main/res/drawable/baseline_visibility_off_24.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/layout/fragment_message.xml b/app/src/main/res/layout/fragment_message.xml
deleted file mode 100644
index be610976..00000000
--- a/app/src/main/res/layout/fragment_message.xml
+++ /dev/null
@@ -1,451 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml
index 2b7817fc..5eac2938 100644
--- a/app/src/main/res/layout/item_message.xml
+++ b/app/src/main/res/layout/item_message.xml
@@ -374,7 +374,7 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true"
- app:layout_constraintBottom_toTopOf="@+id/vSeparatorBody"
+ app:layout_constraintBottom_toTopOf="@+id/bnvActions"
app:layout_constraintEnd_toEndOf="@id/tvHeaders"
app:layout_constraintStart_toStartOf="@id/tvHeaders"
app:layout_constraintTop_toBottomOf="@id/vSeparatorRawHeaders" />
@@ -430,7 +430,7 @@
app:layout_constraintBottom_toTopOf="@+id/vSeparatorAttachments"
app:layout_constraintEnd_toEndOf="@id/tvBody"
app:layout_constraintStart_toStartOf="@id/tvBody"
- app:layout_constraintTop_toBottomOf="@id/vSeparatorBody" />
+ app:layout_constraintTop_toBottomOf="@id/bnvActions" />
-
diff --git a/app/src/main/res/menu/menu_view.xml b/app/src/main/res/menu/menu_view.xml
deleted file mode 100644
index 8db3cdee..00000000
--- a/app/src/main/res/menu/menu_view.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cbc67865..d93cbdc2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -122,7 +122,6 @@
Email address missing
Account missing
Host name missing
- Port number missing
User name missing
Password missing
Drafts folder missing
@@ -150,7 +149,6 @@
Synchronize (receive messages)
Show in unified inbox
Synchronize (days)
- Poll interval (minutes)
Folder %1$s exists
Delete folder permanently?
@@ -168,13 +166,10 @@
Conversation
No messages
- link
- image
Show images
Re: %1$s
Fwd: %1$s
- Show conversation
Mark read
Mark unread
Add star
@@ -217,7 +212,6 @@
Insert image
Add attachment
Show CC/BCC
- Text size
Sender missing
Recipient missing