package eu.faircode.email;
/*
This file is part of Safe email.
Safe email 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.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.Collator;
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.app.ActionBarDrawerToggle;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
public class ActivityView extends ActivityBase implements FragmentManager.OnBackStackChangedListener {
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
static final int LOADER_EXCEPTION = 1;
static final int LOADER_ACCOUNT_CHECK = 2;
static final int LOADER_ACCOUNT_PUT = 3;
static final int LOADER_IDENTITY_PUT = 4;
static final int LOADER_FOLDER_PUT = 5;
static final int LOADER_MESSAGE_ACCOUNT = 6;
static final int LOADER_MESSAGE_VIEW = 7;
static final int LOADER_MESSAGE_SEEN = 8;
static final int LOADER_MESSAGE_EDIT = 9;
static final int LOADER_MESSAGE_SPAM = 10;
static final int LOADER_MESSAGE_TRASH = 11;
static final int LOADER_MESSAGE_MOVE = 12;
static final int LOADER_MESSAGE_ARCHIVE = 13;
static final int LOADER_SEEN_UNTIL = 14;
static final int LOADER_DEBUG_INFO = 15;
static final int REQUEST_VIEW = 1;
static final int REQUEST_UNSEEN = 2;
static final String ACTION_VIEW_MESSAGES = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGES";
static final String ACTION_VIEW_MESSAGE = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGE";
static final String ACTION_EDIT_FOLDER = BuildConfig.APPLICATION_ID + ".EDIT_FOLDER";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
drawerLayout = findViewById(R.id.drawer_layout);
drawerLayout.setScrimColor(Helper.resolveColor(this, R.attr.colorDrawerScrim));
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.app_name, R.string.app_name) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getSupportActionBar().setTitle(getString(R.string.app_name));
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getSupportActionBar().setTitle(getString(R.string.app_name));
}
};
drawerLayout.addDrawerListener(drawerToggle);
drawerList = findViewById(R.id.drawer_list);
drawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
DrawerItem item = (DrawerItem) parent.getAdapter().getItem(position);
switch (item.getId()) {
case -1:
onMenuFolders((long) item.getData());
break;
case R.string.menu_setup:
onMenuSetup();
break;
case R.string.menu_faq:
onMenuFAQ();
break;
case R.string.menu_about:
onMenuAbout();
break;
}
drawerLayout.closeDrawer(drawerList);
}
});
getSupportFragmentManager().addOnBackStackChangedListener(this);
DB.getInstance(this).account().liveAccounts().observe(this, new Observer>() {
@Override
public void onChanged(@Nullable List accounts) {
ArrayAdapterDrawer drawerArray = new ArrayAdapterDrawer(ActivityView.this, R.layout.item_drawer);
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(accounts, new Comparator() {
@Override
public int compare(EntityAccount a1, EntityAccount a2) {
return collator.compare(a1.name, a2.name);
}
});
for (EntityAccount account : accounts)
drawerArray.add(new DrawerItem(-1, R.drawable.baseline_folder_24, account.name, account.id));
drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_settings_applications_24, R.string.menu_setup));
if (getIntentFAQ().resolveActivity(getPackageManager()) != null)
drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_question_answer_24, R.string.menu_faq));
drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_help_24, R.string.menu_about));
drawerList.setAdapter(drawerArray);
}
});
if (getSupportFragmentManager().getFragments().size() == 0) {
Bundle args = new Bundle();
args.putLong("folder", -1);
FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(args);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("unified");
fragmentTransaction.commit();
}
new SimpleLoader() {
@Override
public Long onLoad(Bundle args) throws Throwable {
File file = new File(getContext().getCacheDir(), "crash.log");
if (file.exists()) {
DB db = DB.getInstance(getContext());
EntityFolder drafts = db.folder().getPrimaryDrafts();
if (drafts != null) {
Address to = new InternetAddress("marcel+email@faircode.eu", "FairCode");
// Get version info
StringBuilder sb = new StringBuilder();
sb.append(String.format("%s: %s/%d\r\n", BuildConfig.APPLICATION_ID, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
sb.append(String.format("Android: %s (SDK %d)\r\n", Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
sb.append("\r\n");
// Get device info
sb.append(String.format("Brand: %s\r\n", Build.BRAND));
sb.append(String.format("Manufacturer: %s\r\n", Build.MANUFACTURER));
sb.append(String.format("Model: %s\r\n", Build.MODEL));
sb.append(String.format("Product: %s\r\n", Build.PRODUCT));
sb.append(String.format("Device: %s\r\n", Build.DEVICE));
sb.append(String.format("Host: %s\r\n", Build.HOST));
sb.append(String.format("Display: %s\r\n", Build.DISPLAY));
sb.append(String.format("Id: %s\r\n", Build.ID));
sb.append("\r\n");
BufferedReader in = null;
try {
String line;
in = new BufferedReader(new FileReader(file));
while ((line = in.readLine()) != null)
sb.append(line);
} finally {
if (in != null)
in.close();
}
EntityMessage draft = new EntityMessage();
draft.account = drafts.account;
draft.folder = drafts.id;
draft.to = new Address[]{to};
draft.subject = getString(R.string.app_name) + " crash log";
draft.body = "
" + sb.toString().replaceAll("\\r?\\n", " ") + "
";
draft.received = new Date().getTime();
draft.seen = false;
draft.ui_seen = false;
draft.ui_hide = false;
draft.id = db.message().insertMessage(draft);
file.delete();
return draft.id;
}
}
return null;
}
@Override
public void onLoaded(Bundle args, Long id) {
if (id != null)
startActivity(
new Intent(ActivityView.this, ActivityCompose.class)
.putExtra("action", "edit")
.putExtra("id", id));
}
}.load(this, LOADER_EXCEPTION, new Bundle());
checkIntent(getIntent());
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
@Override
protected void onNewIntent(Intent intent) {
getSupportFragmentManager().popBackStack("unified", 0);
checkIntent(intent);
super.onNewIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
IntentFilter iff = new IntentFilter();
iff.addAction(ACTION_VIEW_MESSAGES);
iff.addAction(ACTION_VIEW_MESSAGE);
iff.addAction(ACTION_EDIT_FOLDER);
lbm.registerReceiver(receiver, iff);
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.unregisterReceiver(receiver);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(drawerList))
drawerLayout.closeDrawer(drawerList);
else
super.onBackPressed();
}
@Override
public void onBackStackChanged() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0)
finish();
else
drawerToggle.setDrawerIndicatorEnabled(count == 1);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
default:
return false;
}
}
private void checkIntent(Intent intent) {
Log.i(Helper.TAG, "View intent=" + intent + " action=" + intent.getAction());
String action = intent.getAction();
intent.setAction(null);
setIntent(intent);
if ("unseen".equals(action)) {
Bundle args = new Bundle();
args.putLong("time", new Date().getTime());
new SimpleLoader