From 4a9f189897b3b8d82fd19caa23923572cd401ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Sch=C3=A4ttgen?= Date: Wed, 18 Sep 2024 12:42:38 +0200 Subject: [PATCH] Add ability to easily assign groups --- .../aegis/ui/MainActivity.java | 77 +++++++++++++++++++ .../main/res/layout/dialog_select_group.xml | 52 +++++++++++++ app/src/main/res/menu/menu_action_mode.xml | 6 ++ app/src/main/res/values/strings.xml | 4 + 4 files changed, 139 insertions(+) create mode 100644 app/src/main/res/layout/dialog_select_group.xml diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 1418c72e9a..6c45f3bb59 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -24,6 +24,7 @@ import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; +import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.Toast; @@ -42,6 +43,7 @@ import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.SortCategory; +import com.beemdevelopment.aegis.helpers.DropdownHelper; import com.beemdevelopment.aegis.helpers.FabScrollHelper; import com.beemdevelopment.aegis.helpers.PermissionHelper; import com.beemdevelopment.aegis.otp.GoogleAuthInfo; @@ -67,6 +69,8 @@ import com.google.android.material.color.MaterialColors; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import com.google.common.base.Strings; import java.util.ArrayList; @@ -79,6 +83,7 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; public class MainActivity extends AegisActivity implements EntryListView.Listener { @@ -488,6 +493,76 @@ private void startAssignIconsActivity(List entries) { assignIconsResultLauncher.launch(assignIconIntent); } + private void startAssignGroupsDialog() { + View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_group, null); + TextInputLayout groupSelectionLayout = view.findViewById(R.id.group_selection_layout); + AutoCompleteTextView groupsSelection = view.findViewById(R.id.group_selection_dropdown); + TextInputLayout newGroupLayout = view.findViewById(R.id.text_group_name_layout); + TextInputEditText newGroupText = view.findViewById(R.id.text_group_name); + + Collection groups = _vaultManager.getVault().getUsedGroups(); + List groupModels = new ArrayList<>(); + groupModels.add(new VaultGroupModel(getString(R.string.new_group))); + groupModels.addAll(groups.stream().map(VaultGroupModel::new).collect(Collectors.toList())); + DropdownHelper.fillDropdown(this, groupsSelection, groupModels); + + AtomicReference groupModelRef = new AtomicReference<>(); + groupsSelection.setOnItemClickListener((parent, view1, position, id) -> { + VaultGroupModel groupModel = (VaultGroupModel) parent.getItemAtPosition(position); + groupModelRef.set(groupModel); + + if (groupModel.isPlaceholder()) { + newGroupLayout.setVisibility(View.VISIBLE); + newGroupText.requestFocus(); + } else { + newGroupLayout.setVisibility(View.GONE); + } + + groupSelectionLayout.setError(null); + }); + + AlertDialog dialog = new MaterialAlertDialogBuilder(this) + .setTitle(R.string.assign_groups) + .setView(view) + .setPositiveButton(android.R.string.ok, null) + .setNegativeButton(android.R.string.cancel, null) + .create(); + + dialog.setOnShowListener(d -> { + Button btnPos = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + btnPos.setOnClickListener(v -> { + VaultGroupModel groupModel = groupModelRef.get(); + if (groupModel == null) { + groupSelectionLayout.setError(getString(R.string.error_required_field)); + return; + } + + if (groupModel.isPlaceholder()) { + String newGroupName = newGroupText.getText().toString().trim(); + if (newGroupName.isEmpty()) { + newGroupLayout.setError(getString(R.string.error_required_field)); + return; + } + + VaultGroup group = new VaultGroup(newGroupName); + _vaultManager.getVault().addGroup(group); + groupModel = new VaultGroupModel(group); + } + + for (VaultEntry selectedEntry : _selectedEntries) { + selectedEntry.addGroup(groupModel.getUUID()); + } + + dialog.dismiss(); + saveAndBackupVault(); + _actionMode.finish(); + setGroups(_vaultManager.getVault().getUsedGroups()); + }); + }); + + Dialogs.showSecureDialog(dialog); + } + private void startIntroActivity() { if (!_isDoingIntro) { Intent intro = new Intent(this, IntroActivity.class); @@ -1355,6 +1430,8 @@ public boolean onActionItemClicked(ActionMode mode, MenuItem item) { } else if (itemId == R.id.action_assign_icons) { startAssignIconsActivity(_selectedEntries); mode.finish(); + } else if (itemId == R.id.action_assign_groups) { + startAssignGroupsDialog(); } else { return false; } diff --git a/app/src/main/res/layout/dialog_select_group.xml b/app/src/main/res/layout/dialog_select_group.xml new file mode 100644 index 0000000000..4d75463423 --- /dev/null +++ b/app/src/main/res/layout/dialog_select_group.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_action_mode.xml b/app/src/main/res/menu/menu_action_mode.xml index e9be8f1821..ef65ccde8f 100644 --- a/app/src/main/res/menu/menu_action_mode.xml +++ b/app/src/main/res/menu/menu_action_mode.xml @@ -33,6 +33,12 @@ android:orderInCategory="100" app:showAsAction="never"/> + + Edit Select all Assign icons + Assign to group + Select a group you wish to assign the selected entries to. + Select group Favorite Unfavorite ERROR @@ -251,6 +254,7 @@ Copied Errors copied to the clipboard Version copied to the clipboard + This field is required An error occurred An error occurred while trying to unlock the vault An error occurred while trying to unlock the vault. Your vault file might be corrupt.