Use dialog fragment to ask sure

This commit is contained in:
M66B 2019-06-30 13:06:12 +02:00
parent 5e65931e37
commit 8a0fafa620
2 changed files with 263 additions and 172 deletions

View File

@ -0,0 +1,75 @@
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.
FairEmail 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 FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
public class FragmentAsk extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
String question = getArguments().getString("question");
View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_message, null);
TextView tvMessage = dview.findViewById(R.id.tvMessage);
tvMessage.setText(question);
return new AlertDialog.Builder(getContext())
.setView(dview)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sendResult(Activity.RESULT_OK);
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
sendResult(Activity.RESULT_CANCELED);
}
})
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
sendResult(Activity.RESULT_CANCELED);
}
})
.create();
}
private void sendResult(int result) {
Fragment target = getTargetFragment();
if (target != null)
target.onActivityResult(getTargetRequestCode(), result, null);
}
}

View File

@ -19,8 +19,9 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
@ -78,6 +79,9 @@ public class FragmentFolder extends FragmentBase {
private boolean saving = false;
private boolean deletable = false;
private static final int REQUEST_SAVE_CHANGES = 101;
private static final int REQUEST_DELETE_FOLDER = 102;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -172,6 +176,157 @@ public class FragmentFolder extends FragmentBase {
return view;
}
@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle args = new Bundle();
args.putLong("id", id);
new SimpleTask<EntityFolder>() {
@Override
protected EntityFolder onExecute(Context context, Bundle args) {
long id = args.getLong("id");
return DB.getInstance(context).folder().getFolder(id);
}
@Override
protected void onExecuted(Bundle args, EntityFolder folder) {
if (savedInstanceState == null) {
etName.setText(folder == null ? null : folder.name);
etDisplay.setText(folder == null ? null : folder.display);
etDisplay.setHint(folder == null ? null : Helper.localizeFolderName(getContext(), folder.name));
cbHide.setChecked(folder == null ? false : folder.hide);
cbUnified.setChecked(folder == null ? false : folder.unified);
cbNavigation.setChecked(folder == null ? false : folder.navigation);
cbNotify.setChecked(folder == null ? false : folder.notify);
cbSynchronize.setChecked(folder == null || folder.synchronize);
cbPoll.setChecked(folder == null ? false : folder.poll);
cbDownload.setChecked(folder == null ? true : folder.download);
etSyncDays.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_SYNC : folder.sync_days));
if (folder != null && folder.keep_days == Integer.MAX_VALUE)
cbKeepAll.setChecked(true);
else
etKeepDays.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_KEEP : folder.keep_days));
cbAutoDelete.setChecked(folder == null ? false : folder.auto_delete);
cbAutoDelete.setVisibility(folder != null && EntityFolder.TRASH.equals(folder.type) ? View.VISIBLE : View.GONE);
}
// Consider previous save as cancelled
pbWait.setVisibility(View.GONE);
Helper.setViewsEnabled(view, true);
etName.setEnabled(folder == null);
cbPoll.setEnabled(cbSynchronize.isChecked());
cbDownload.setEnabled(cbSynchronize.isChecked());
etKeepDays.setEnabled(!cbKeepAll.isChecked());
cbAutoDelete.setEnabled(!cbKeepAll.isChecked());
btnSave.setEnabled(true);
subscribed = (folder == null ? null : folder.subscribed != null && folder.subscribed);
deletable = (folder != null && EntityFolder.USER.equals(folder.type));
getActivity().invalidateOptionsMenu();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(this, args, "folder:get");
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_SAVE_CHANGES:
if (resultCode == Activity.RESULT_OK) {
new Handler().post(new Runnable() {
@Override
public void run() {
scroll.smoothScrollTo(0, btnSave.getBottom());
}
});
onSave(false);
} else
getFragmentManager().popBackStack();
break;
case REQUEST_DELETE_FOLDER:
if (resultCode == Activity.RESULT_OK)
onDelete();
break;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_folder, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
boolean subscriptions = prefs.getBoolean("subscriptions", false);
menu.findItem(R.id.menu_subscribe).setChecked(subscribed != null && subscribed);
menu.findItem(R.id.menu_subscribe).setVisible(subscriptions && id > 0 && subscribed != null);
menu.findItem(R.id.menu_delete).setVisible(id > 0 && !saving && deletable);
super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_subscribe:
subscribed = !item.isChecked();
item.setChecked(subscribed);
onMenuSubscribe();
return true;
case R.id.menu_delete:
onMenuDelete();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void onMenuSubscribe() {
Bundle args = new Bundle();
args.putLong("id", id);
args.putBoolean("subscribed", subscribed);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean subscribed = args.getBoolean("subscribed");
EntityOperation.subscribe(context, id, subscribed);
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(this, args, "folder:subscribe");
}
private void onMenuDelete() {
Bundle aargs = new Bundle();
aargs.putString("question", getString(R.string.title_folder_delete));
FragmentAsk ask = new FragmentAsk();
ask.setArguments(aargs);
ask.setTargetFragment(FragmentFolder.this, REQUEST_DELETE_FOLDER);
ask.show(getFragmentManager(), "folder:delete");
}
private void onSave(boolean should) {
Bundle args = new Bundle();
args.putLong("id", id);
@ -337,29 +492,15 @@ public class FragmentFolder extends FragmentBase {
@Override
protected void onExecuted(Bundle args, Boolean dirty) {
if (dirty)
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
.setMessage(R.string.title_ask_save)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new Handler().post(new Runnable() {
@Override
public void run() {
scroll.smoothScrollTo(0, btnSave.getBottom());
}
});
onSave(false);
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
getFragmentManager().popBackStack();
}
})
.show();
else
if (dirty) {
Bundle aargs = new Bundle();
aargs.putString("question", getString(R.string.title_ask_save));
FragmentAsk ask = new FragmentAsk();
ask.setArguments(aargs);
ask.setTargetFragment(FragmentFolder.this, REQUEST_SAVE_CHANGES);
ask.show(getFragmentManager(), "folder:save");
} else
getFragmentManager().popBackStack();
}
@ -373,171 +514,46 @@ public class FragmentFolder extends FragmentBase {
}.execute(FragmentFolder.this, args, "folder:save");
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_folder, menu);
super.onCreateOptionsMenu(menu, inflater);
}
private void onDelete() {
Helper.setViewsEnabled(view, false);
pbSave.setVisibility(View.VISIBLE);
@Override
public void onPrepareOptionsMenu(Menu menu) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
boolean subscriptions = prefs.getBoolean("subscriptions", false);
menu.findItem(R.id.menu_subscribe).setChecked(subscribed != null && subscribed);
menu.findItem(R.id.menu_subscribe).setVisible(subscriptions && id > 0 && subscribed != null);
menu.findItem(R.id.menu_delete).setVisible(id > 0 && !saving && deletable);
super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_subscribe:
subscribed = !item.isChecked();
item.setChecked(subscribed);
onMenuSubscribe();
return true;
case R.id.menu_delete:
onMenuDelete();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void onMenuSubscribe() {
Bundle args = new Bundle();
args.putLong("id", id);
args.putBoolean("subscribed", subscribed);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean subscribed = args.getBoolean("subscribed");
EntityOperation.subscribe(context, id, subscribed);
DB db = DB.getInstance(context);
int count = db.operation().getOperationCount(id, null);
if (count > 0)
throw new IllegalArgumentException(
context.getResources().getQuantityString(
R.plurals.title_notification_operations, count, count));
db.folder().setFolderTbd(id);
ServiceSynchronize.reload(context, "delete folder");
return null;
}
@Override
protected void onExecuted(Bundle args, Void data) {
getFragmentManager().popBackStack();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(this, args, "folder:subscribe");
}
private void onMenuDelete() {
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
.setMessage(R.string.title_folder_delete)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Helper.setViewsEnabled(view, false);
pbSave.setVisibility(View.VISIBLE);
Bundle args = new Bundle();
args.putLong("id", id);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id");
DB db = DB.getInstance(context);
int count = db.operation().getOperationCount(id, null);
if (count > 0)
throw new IllegalArgumentException(
context.getResources().getQuantityString(
R.plurals.title_notification_operations, count, count));
db.folder().setFolderTbd(id);
ServiceSynchronize.reload(context, "delete folder");
return null;
}
@Override
protected void onExecuted(Bundle args, Void data) {
getFragmentManager().popBackStack();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.setViewsEnabled(view, true);
pbSave.setVisibility(View.GONE);
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(FragmentFolder.this, args, "folder:delete");
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle args = new Bundle();
args.putLong("id", id);
new SimpleTask<EntityFolder>() {
@Override
protected EntityFolder onExecute(Context context, Bundle args) {
long id = args.getLong("id");
return DB.getInstance(context).folder().getFolder(id);
}
@Override
protected void onExecuted(Bundle args, EntityFolder folder) {
if (savedInstanceState == null) {
etName.setText(folder == null ? null : folder.name);
etDisplay.setText(folder == null ? null : folder.display);
etDisplay.setHint(folder == null ? null : Helper.localizeFolderName(getContext(), folder.name));
cbHide.setChecked(folder == null ? false : folder.hide);
cbUnified.setChecked(folder == null ? false : folder.unified);
cbNavigation.setChecked(folder == null ? false : folder.navigation);
cbNotify.setChecked(folder == null ? false : folder.notify);
cbSynchronize.setChecked(folder == null || folder.synchronize);
cbPoll.setChecked(folder == null ? false : folder.poll);
cbDownload.setChecked(folder == null ? true : folder.download);
etSyncDays.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_SYNC : folder.sync_days));
if (folder != null && folder.keep_days == Integer.MAX_VALUE)
cbKeepAll.setChecked(true);
else
etKeepDays.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_KEEP : folder.keep_days));
cbAutoDelete.setChecked(folder == null ? false : folder.auto_delete);
cbAutoDelete.setVisibility(folder != null && EntityFolder.TRASH.equals(folder.type) ? View.VISIBLE : View.GONE);
}
// Consider previous save as cancelled
pbWait.setVisibility(View.GONE);
Helper.setViewsEnabled(view, true);
pbSave.setVisibility(View.GONE);
etName.setEnabled(folder == null);
cbPoll.setEnabled(cbSynchronize.isChecked());
cbDownload.setEnabled(cbSynchronize.isChecked());
etKeepDays.setEnabled(!cbKeepAll.isChecked());
cbAutoDelete.setEnabled(!cbKeepAll.isChecked());
btnSave.setEnabled(true);
subscribed = (folder == null ? null : folder.subscribed != null && folder.subscribed);
deletable = (folder != null && EntityFolder.USER.equals(folder.type));
getActivity().invalidateOptionsMenu();
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(this, args, "folder:get");
}.execute(FragmentFolder.this, args, "folder:delete");
}
}