mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-25 08:16:07 +00:00
Wrapping a ``RecyclerView`` with a ``NestedScrollView`` breaks its recycling functionality because the view height is stretched to fit the full list of entries. We never noticed performance issues in these two cases because these lists never get very long. Let's fix these cases anyway so that we don't accidentally base a new use of a ``RecyclerView`` on this broken pattern. Also renamed ``list_slots`` to ``list_groups``. Must have been a copy-paste error.
156 lines
4.9 KiB
Java
156 lines
4.9 KiB
Java
package com.beemdevelopment.aegis.ui;
|
|
|
|
import android.os.Bundle;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
|
|
import androidx.activity.OnBackPressedCallback;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import com.beemdevelopment.aegis.R;
|
|
import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
|
|
import com.beemdevelopment.aegis.ui.views.GroupAdapter;
|
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
public class GroupManagerActivity extends AegisActivity implements GroupAdapter.Listener {
|
|
private GroupAdapter _adapter;
|
|
private HashSet<String> _removedGroups;
|
|
private RecyclerView _groupsView;
|
|
private View _emptyStateView;
|
|
private BackPressHandler _backPressHandler;
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
if (abortIfOrphan(savedInstanceState)) {
|
|
return;
|
|
}
|
|
setContentView(R.layout.activity_groups);
|
|
setSupportActionBar(findViewById(R.id.toolbar));
|
|
if (getSupportActionBar() != null) {
|
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
|
}
|
|
_backPressHandler = new BackPressHandler();
|
|
getOnBackPressedDispatcher().addCallback(this, _backPressHandler);
|
|
|
|
if (savedInstanceState != null) {
|
|
List<String> groups = savedInstanceState.getStringArrayList("removedGroups");
|
|
_removedGroups = new HashSet<>(Objects.requireNonNull(groups));
|
|
} else {
|
|
_removedGroups = new HashSet<>();
|
|
}
|
|
|
|
_adapter = new GroupAdapter(this);
|
|
_groupsView = findViewById(R.id.list_groups);
|
|
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
|
_groupsView.setLayoutManager(layoutManager);
|
|
_groupsView.setAdapter(_adapter);
|
|
_groupsView.setNestedScrollingEnabled(false);
|
|
|
|
for (String group : _vaultManager.getVault().getGroups()) {
|
|
_adapter.addGroup(group);
|
|
}
|
|
|
|
_emptyStateView = findViewById(R.id.vEmptyList);
|
|
updateEmptyState();
|
|
}
|
|
|
|
@Override
|
|
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
|
super.onSaveInstanceState(outState);
|
|
outState.putStringArrayList("removedGroups", new ArrayList<>(_removedGroups));
|
|
}
|
|
|
|
@Override
|
|
public void onRemoveGroup(String group) {
|
|
Dialogs.showSecureDialog(new AlertDialog.Builder(this)
|
|
.setTitle(R.string.remove_group)
|
|
.setMessage(R.string.remove_group_description)
|
|
.setPositiveButton(android.R.string.yes, (dialog, whichButton) -> {
|
|
_removedGroups.add(group);
|
|
_adapter.removeGroup(group);
|
|
_backPressHandler.setEnabled(true);
|
|
updateEmptyState();
|
|
})
|
|
.setNegativeButton(android.R.string.no, null)
|
|
.create());
|
|
}
|
|
|
|
private void saveAndFinish() {
|
|
if (!_removedGroups.isEmpty()) {
|
|
for (VaultEntry entry : _vaultManager.getVault().getEntries()) {
|
|
if (_removedGroups.contains(entry.getGroup())) {
|
|
entry.setGroup(null);
|
|
}
|
|
}
|
|
|
|
saveAndBackupVault();
|
|
}
|
|
|
|
finish();
|
|
}
|
|
|
|
private void discardAndFinish() {
|
|
if (_removedGroups.isEmpty()) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
Dialogs.showDiscardDialog(this,
|
|
(dialog, which) -> saveAndFinish(),
|
|
(dialog, which) -> finish());
|
|
}
|
|
|
|
@Override
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
getMenuInflater().inflate(R.menu.menu_groups, menu);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
case android.R.id.home:
|
|
discardAndFinish();
|
|
break;
|
|
case R.id.action_save:
|
|
saveAndFinish();
|
|
break;
|
|
default:
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void updateEmptyState() {
|
|
if (_adapter.getItemCount() > 0) {
|
|
_groupsView.setVisibility(View.VISIBLE);
|
|
_emptyStateView.setVisibility(View.GONE);
|
|
} else {
|
|
_groupsView.setVisibility(View.GONE);
|
|
_emptyStateView.setVisibility(View.VISIBLE);
|
|
}
|
|
}
|
|
|
|
private class BackPressHandler extends OnBackPressedCallback {
|
|
public BackPressHandler() {
|
|
super(false);
|
|
}
|
|
|
|
@Override
|
|
public void handleOnBackPressed() {
|
|
discardAndFinish();
|
|
}
|
|
}
|
|
}
|