Add checkbox dialog to wipe vault before import

Only show dialog when vault contains entries

Add improvements from review
This commit is contained in:
Michael Schättgen 2020-08-16 03:33:53 +02:00
parent 7d38bc9b71
commit 0f6b0dddbe
7 changed files with 92 additions and 3 deletions

View file

@ -231,6 +231,37 @@ public class Dialogs {
showTextInputDialog(context, setPasswordMessageId, messageId, R.string.password, listener, dismissListener, true);
}
public static void showCheckboxDialog(Context context, @StringRes int titleId, @StringRes int messageId, @StringRes int checkboxMessageId, CheckboxInputListener listener) {
View view = LayoutInflater.from(context).inflate(R.layout.dialog_checkbox, null);
CheckBox checkBox = view.findViewById(R.id.checkbox);
checkBox.setText(checkboxMessageId);
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle(titleId)
.setView(view)
.setNegativeButton(R.string.no, (dialog1, which) ->
listener.onCheckboxInputResult(false))
.setPositiveButton(R.string.yes, (dialog1, which) ->
listener.onCheckboxInputResult(checkBox.isChecked()));
if (messageId != 0) {
builder.setMessage(messageId);
}
AlertDialog dialog = builder.create();
final AtomicReference<Button> buttonOK = new AtomicReference<>();
dialog.setOnShowListener(d -> {
Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
button.setEnabled(false);
buttonOK.set(button);
});
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> buttonOK.get().setEnabled(isChecked));
showSecureDialog(dialog);
}
public static void showNumberPickerDialog(Activity activity, NumberInputListener listener) {
View view = activity.getLayoutInflater().inflate(R.layout.dialog_number_picker, null);
NumberPicker numberPicker = view.findViewById(R.id.numberPicker);
@ -350,6 +381,10 @@ public class Dialogs {
.create());
}
public interface CheckboxInputListener {
void onCheckboxInputResult(boolean checkbox);
}
public interface NumberInputListener {
void onNumberInputResult(int number);
}

View file

@ -38,6 +38,7 @@ import com.beemdevelopment.aegis.ui.models.ImportEntry;
import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
import com.beemdevelopment.aegis.util.UUIDMap;
import com.beemdevelopment.aegis.vault.Vault;
import com.beemdevelopment.aegis.vault.VaultBackupManager;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
@ -657,6 +658,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
Intent intent = new Intent(getActivity(), SelectEntriesActivity.class);
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
intent.putExtra("errors", (ArrayList<DatabaseImporterEntryException>) result.getErrors());
intent.putExtra("vaultContainsEntries", _vault.getEntries().size() > 0);
startActivityForResult(intent, CODE_SELECT_ENTRIES);
}
@ -719,6 +721,11 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
return;
}
boolean wipeEntries = data.getBooleanExtra("wipeEntries", false);
if (wipeEntries) {
_vault.wipeEntries();
}
List<ImportEntry> selectedEntries = (ArrayList<ImportEntry>) data.getSerializableExtra("entries");
for (ImportEntry selectedEntry : selectedEntries) {
VaultEntry savedEntry = _importerEntries.getByUUID(selectedEntry.getUUID());

View file

@ -25,10 +25,12 @@ import com.getbase.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class SelectEntriesActivity extends AegisActivity {
private ImportEntriesAdapter _adapter;
private FabScrollHelper _fabScrollHelper;
private boolean _vaultContainsEntries;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -57,6 +59,7 @@ public class SelectEntriesActivity extends AegisActivity {
Intent intent = getIntent();
List<ImportEntry> entries = (ArrayList<ImportEntry>) intent.getSerializableExtra("entries");
List<DatabaseImporterEntryException> errors = (ArrayList<DatabaseImporterEntryException>) intent.getSerializableExtra("errors");
_vaultContainsEntries = intent.getBooleanExtra("vaultContainsEntries", false);
for (ImportEntry entry : entries) {
_adapter.addEntry(entry);
@ -67,7 +70,13 @@ public class SelectEntriesActivity extends AegisActivity {
}
FloatingActionButton fabMenu = findViewById(R.id.fab);
fabMenu.setOnClickListener(v -> returnSelectedEntries());
fabMenu.setOnClickListener(v -> {
if (_vaultContainsEntries) {
showWipeEntriesDialog();
} else {
returnSelectedEntries(false);
}
});
_fabScrollHelper = new FabScrollHelper(fabMenu);
}
@ -100,10 +109,19 @@ public class SelectEntriesActivity extends AegisActivity {
.create());
}
private void returnSelectedEntries() {
List<ImportEntry> entries = _adapter.getCheckedEntries();
private void showWipeEntriesDialog() {
Dialogs.showCheckboxDialog(this, R.string.dialog_wipe_entries_title,
R.string.dialog_wipe_entries_message,
R.string.dialog_wipe_entries_checkbox,
this::returnSelectedEntries
);
}
private void returnSelectedEntries(boolean wipeEntries) {
Intent intent = new Intent();
List<ImportEntry> entries = _adapter.getCheckedEntries();
intent.putExtra("entries", (ArrayList<ImportEntry>) entries);
intent.putExtra("wipeEntries", wipeEntries);
setResult(RESULT_OK, intent);
finish();
}

View file

@ -44,6 +44,13 @@ public class UUIDMap <T extends UUIDMap.Value> implements Iterable<T>, Serializa
return oldValue;
}
/**
* Clears the internal map.
*/
public void wipe() {
_map.clear();
}
/**
* Replaces an old value (with the same UUID as the new given value) in the
* internal map with the new given value.

View file

@ -154,6 +154,10 @@ public class VaultManager {
return _vault.getEntries().remove(entry);
}
public void wipeEntries() {
_vault.getEntries().wipe();
}
public VaultEntry replaceEntry(VaultEntry entry) {
return _vault.getEntries().replace(entry);
}