Use dialog fragment for folder actions

pull/157/head
M66B 6 years ago
parent 8cec626e72
commit 4f5fa6791e

@ -22,7 +22,6 @@ package eu.faircode.email;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
@ -44,6 +43,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
@ -51,8 +51,6 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
import java.text.Collator; import java.text.Collator;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -62,11 +60,13 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import static android.app.Activity.RESULT_OK;
public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder> { public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder> {
private Context context; private Context context;
private LayoutInflater inflater; private LayoutInflater inflater;
private LifecycleOwner owner; private LifecycleOwner owner;
private View parentView; private Fragment parentFragment;
private boolean show_hidden; private boolean show_hidden;
private long account; private long account;
@ -400,7 +400,12 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.string.title_synchronize_now: case R.string.title_synchronize_now:
onActionSynchronizeNow(false); Bundle args = new Bundle();
args.putLong("folder", folder.id);
args.putBoolean("all", false);
Intent data = new Intent();
data.putExtra("args", args);
parentFragment.onActivityResult(FragmentFolders.REQUEST_SYNC, RESULT_OK, data);
return true; return true;
case R.string.title_synchronize_all: case R.string.title_synchronize_all:
@ -458,92 +463,17 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
} }
} }
private void onActionSynchronizeNow(boolean all) {
Bundle args = new Bundle();
args.putBoolean("all", all);
args.putLong("folder", folder.id);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
boolean all = args.getBoolean("all");
long fid = args.getLong("folder");
if (!ConnectionHelper.getNetworkState(context).isSuitable())
throw new IllegalStateException(context.getString(R.string.title_no_internet));
boolean now = true;
DB db = DB.getInstance(context);
try {
db.beginTransaction();
EntityFolder folder = db.folder().getFolder(fid);
if (folder == null)
return null;
if (all) {
db.folder().setFolderInitialize(folder.id, Integer.MAX_VALUE);
db.folder().setFolderKeep(folder.id, Integer.MAX_VALUE);
}
EntityOperation.sync(context, folder.id, true);
if (folder.account != null) {
EntityAccount account = db.account().getAccount(folder.account);
if (account != null && !"connected".equals(account.state))
now = false;
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (!now)
throw new IllegalArgumentException(context.getString(R.string.title_no_connection));
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
if (ex instanceof IllegalStateException) {
Snackbar snackbar = Snackbar.make(parentView, ex.getMessage(), Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override
public void onClick(View view) {
context.startActivity(
new Intent(context, ActivitySetup.class)
.putExtra("tab", "connection"));
}
});
snackbar.show();
} else if (ex instanceof IllegalArgumentException)
Snackbar.make(parentView, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(context, owner, ex);
}
}.execute(context, owner, args, "folder:sync");
}
private void onActionSynchronizeAll() { private void onActionSynchronizeAll() {
View dview = LayoutInflater.from(context).inflate(R.layout.dialog_message, null); Bundle aargs = new Bundle();
TextView tvMessage = dview.findViewById(R.id.tvMessage); aargs.putString("question",
context.getString(R.string.title_ask_sync_all, folder.getDisplayName(context)));
tvMessage.setText(context.getString(R.string.title_ask_sync_all, folder.getDisplayName(context))); aargs.putLong("folder", folder.id);
aargs.putBoolean("all", true);
new DialogBuilderLifecycle(context, owner)
.setView(dview) FragmentDialogAsk ask = new FragmentDialogAsk();
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { ask.setArguments(aargs);
@Override ask.setTargetFragment(parentFragment, FragmentFolders.REQUEST_SYNC);
public void onClick(DialogInterface dialog, int which) { ask.show(parentFragment.getFragmentManager(), "folder:sync");
onActionSynchronizeNow(true);
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
private void onActionProperty(int property, boolean enabled) { private void onActionProperty(int property, boolean enabled) {
@ -592,87 +522,26 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
} }
private void OnActionDeleteLocal(final boolean browsed) { private void OnActionDeleteLocal(final boolean browsed) {
View dview = LayoutInflater.from(context).inflate(R.layout.dialog_message, null); Bundle aargs = new Bundle();
TextView tvMessage = dview.findViewById(R.id.tvMessage); aargs.putString("question", context.getString(R.string.title_ask_delete_local));
aargs.putLong("folder", folder.id);
tvMessage.setText(context.getText(R.string.title_ask_delete_local)); aargs.putBoolean("browsed", browsed);
new DialogBuilderLifecycle(context, owner) FragmentDialogAsk ask = new FragmentDialogAsk();
.setView(dview) ask.setArguments(aargs);
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { ask.setTargetFragment(parentFragment, FragmentFolders.REQUEST_DELETE_LOCAL);
@Override ask.show(parentFragment.getFragmentManager(), "folder:delete_local");
public void onClick(DialogInterface dialog, int which) {
Bundle args = new Bundle();
args.putLong("id", folder.id);
args.putBoolean("browsed", browsed);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean browsed = args.getBoolean("browsed");
Log.i("Delete local messages browsed=" + browsed);
if (browsed)
DB.getInstance(context).message().deleteBrowsedMessages(id);
else
DB.getInstance(context).message().deleteLocalMessages(id);
return null;
}
@Override
public void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(context, owner, ex);
}
}.execute(context, owner, args, "folder:delete:local");
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
private void onActionEmptyTrash() { private void onActionEmptyTrash() {
new DialogBuilderLifecycle(context, owner) Bundle aargs = new Bundle();
.setMessage(R.string.title_empty_trash_ask) aargs.putString("question", context.getString(R.string.title_empty_trash_ask));
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { aargs.putLong("folder", folder.id);
@Override
public void onClick(DialogInterface dialog, int which) { FragmentDialogAsk ask = new FragmentDialogAsk();
ask.setArguments(aargs);
Bundle args = new Bundle(); ask.setTargetFragment(parentFragment, FragmentFolders.REQUEST_EMPTY_TRASH);
args.putLong("folder", folder.id); ask.show(parentFragment.getFragmentManager(), "folder:empty_trash");
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long folder = args.getLong("folder");
DB db = DB.getInstance(context);
try {
db.beginTransaction();
List<Long> ids = db.message().getMessageByFolder(folder);
for (Long id : ids) {
EntityMessage message = db.message().getMessage(id);
if (message.msgid != null || message.uid != null)
EntityOperation.queue(context, message, EntityOperation.DELETE);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(context, owner, ex);
}
}.execute(context, owner, args, "folder:delete");
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
private void onActionEditRules() { private void onActionEditRules() {
@ -730,12 +599,12 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
} }
} }
AdapterFolder(Context context, LifecycleOwner owner, View parentView, AdapterFolder(Context context, LifecycleOwner owner, Fragment parentFragment,
long account, boolean show_hidden, IFolderSelectedListener listener) { long account, boolean show_hidden, IFolderSelectedListener listener) {
this.context = context; this.context = context;
this.inflater = LayoutInflater.from(context); this.inflater = LayoutInflater.from(context);
this.owner = owner; this.owner = owner;
this.parentView = parentView; this.parentFragment = parentFragment;
this.show_hidden = show_hidden; this.show_hidden = show_hidden;
this.account = account; this.account = account;
this.listener = listener; this.listener = listener;

@ -78,14 +78,15 @@ public class FragmentDialogFolder extends DialogFragment {
folders = new ArrayList<>(); folders = new ArrayList<>();
long account = args.getLong("account"); long account = args.getLong("account");
AdapterFolder adapter = new AdapterFolder(getContext(), owner, getView(), account, false, AdapterFolder adapter = new AdapterFolder(
new AdapterFolder.IFolderSelectedListener() { getContext(), owner, FragmentDialogFolder.this,
@Override account, false, new AdapterFolder.IFolderSelectedListener() {
public void onFolderSelected(TupleFolderEx folder) { @Override
dismiss(); public void onFolderSelected(TupleFolderEx folder) {
sendResult(RESULT_OK, folder.id); dismiss();
} sendResult(RESULT_OK, folder.id);
}); }
});
rvFolder.setAdapter(adapter); rvFolder.setAdapter(adapter);

@ -52,6 +52,8 @@ import com.google.android.material.snackbar.Snackbar;
import java.util.List; import java.util.List;
import static android.app.Activity.RESULT_OK;
public class FragmentFolders extends FragmentBase { public class FragmentFolders extends FragmentBase {
private ViewGroup view; private ViewGroup view;
private SwipeRefreshLayout swipeRefresh; private SwipeRefreshLayout swipeRefresh;
@ -70,6 +72,10 @@ public class FragmentFolders extends FragmentBase {
private String searching = null; private String searching = null;
private AdapterFolder adapter; private AdapterFolder adapter;
static final int REQUEST_SYNC = 1;
static final int REQUEST_DELETE_LOCAL = 2;
static final int REQUEST_EMPTY_TRASH = 3;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -144,7 +150,9 @@ public class FragmentFolders extends FragmentBase {
itemDecorator.setDrawable(getContext().getDrawable(R.drawable.divider)); itemDecorator.setDrawable(getContext().getDrawable(R.drawable.divider));
rvFolder.addItemDecoration(itemDecorator); rvFolder.addItemDecoration(itemDecorator);
adapter = new AdapterFolder(getContext(), getViewLifecycleOwner(), view, account, show_hidden, null); adapter = new AdapterFolder(
getContext(), getViewLifecycleOwner(), this,
account, show_hidden, null);
rvFolder.setAdapter(adapter); rvFolder.setAdapter(adapter);
fab.setOnClickListener(new View.OnClickListener() { fab.setOnClickListener(new View.OnClickListener() {
@ -418,4 +426,160 @@ public class FragmentFolders extends FragmentBase {
getActivity().invalidateOptionsMenu(); getActivity().invalidateOptionsMenu();
adapter.setShowHidden(show_hidden); adapter.setShowHidden(show_hidden);
} }
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_SYNC:
if (resultCode == RESULT_OK && data != null) {
Bundle args = data.getBundleExtra("args");
onSync(args.getLong("folder"), args.getBoolean("all"));
}
break;
case REQUEST_DELETE_LOCAL:
if (resultCode == RESULT_OK && data != null) {
Bundle args = data.getBundleExtra("args");
onDeleteLocal(args.getLong("folder"), args.getBoolean("browsed"));
}
break;
case REQUEST_EMPTY_TRASH:
if (resultCode == RESULT_OK && data != null) {
Bundle args = data.getBundleExtra("args");
onEmptyTrash(args.getLong("folder"));
}
break;
}
}
private void onSync(long folder, boolean all) {
Bundle args = new Bundle();
args.putBoolean("all", all);
args.putLong("folder", folder);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
boolean all = args.getBoolean("all");
long fid = args.getLong("folder");
if (!ConnectionHelper.getNetworkState(context).isSuitable())
throw new IllegalStateException(context.getString(R.string.title_no_internet));
boolean now = true;
DB db = DB.getInstance(context);
try {
db.beginTransaction();
EntityFolder folder = db.folder().getFolder(fid);
if (folder == null)
return null;
if (all) {
db.folder().setFolderInitialize(folder.id, Integer.MAX_VALUE);
db.folder().setFolderKeep(folder.id, Integer.MAX_VALUE);
}
EntityOperation.sync(context, folder.id, true);
if (folder.account != null) {
EntityAccount account = db.account().getAccount(folder.account);
if (account != null && !"connected".equals(account.state))
now = false;
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (!now)
throw new IllegalArgumentException(context.getString(R.string.title_no_connection));
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
if (ex instanceof IllegalStateException) {
Snackbar snackbar = Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(
new Intent(getContext(), ActivitySetup.class)
.putExtra("tab", "connection"));
}
});
snackbar.show();
} else if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(getContext(), getViewLifecycleOwner(), args, "folder:sync");
}
private void onDeleteLocal(long folder, boolean browsed) {
Bundle args = new Bundle();
args.putLong("id", folder);
args.putBoolean("browsed", browsed);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean browsed = args.getBoolean("browsed");
Log.i("Delete local messages browsed=" + browsed);
if (browsed)
DB.getInstance(context).message().deleteBrowsedMessages(id);
else
DB.getInstance(context).message().deleteLocalMessages(id);
return null;
}
@Override
public void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(getContext(), getViewLifecycleOwner(), args, "folder:delete:local");
}
private void onEmptyTrash(long folder) {
Bundle args = new Bundle();
args.putLong("folder", folder);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long folder = args.getLong("folder");
DB db = DB.getInstance(context);
try {
db.beginTransaction();
List<Long> ids = db.message().getMessageByFolder(folder);
for (Long id : ids) {
EntityMessage message = db.message().getMessage(id);
if (message.msgid != null || message.uid != null)
EntityOperation.queue(context, message, EntityOperation.DELETE);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(getContext(), getViewLifecycleOwner(), args, "folder:delete");
}
}
Loading…
Cancel
Save