mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-19 16:30:23 +00:00
Merge pull request #760 from michaelschattgen/feature/usage-count
Add usage count to entries
This commit is contained in:
commit
c27c4f0ac5
16 changed files with 235 additions and 1 deletions
|
@ -22,6 +22,8 @@ import android.widget.AutoCompleteTextView;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -100,6 +102,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
private TextInputEditText _textDigits;
|
||||
private TextInputLayout _textDigitsLayout;
|
||||
private TextInputEditText _textSecret;
|
||||
private TextInputEditText _textUsageCount;
|
||||
|
||||
private AutoCompleteTextView _dropdownType;
|
||||
private AutoCompleteTextView _dropdownAlgo;
|
||||
|
@ -150,6 +153,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
_textDigits = findViewById(R.id.text_digits);
|
||||
_textDigitsLayout = findViewById(R.id.text_digits_layout);
|
||||
_textSecret = findViewById(R.id.text_secret);
|
||||
_textUsageCount = findViewById(R.id.text_usage_count);
|
||||
_dropdownType = findViewById(R.id.dropdown_type);
|
||||
DropdownHelper.fillDropdown(this, _dropdownType, R.array.otp_types_array);
|
||||
_dropdownAlgoLayout = findViewById(R.id.dropdown_algo_layout);
|
||||
|
@ -279,6 +283,8 @@ public class EditEntryActivity extends AegisActivity {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
_textUsageCount.setText(getPreferences().getUsageCount(entryUUID).toString());
|
||||
}
|
||||
|
||||
private void updateAdvancedFieldStatus(String otpType) {
|
||||
|
@ -405,6 +411,14 @@ public class EditEntryActivity extends AegisActivity {
|
|||
case R.id.action_edit_icon:
|
||||
startIconSelection();
|
||||
break;
|
||||
case R.id.action_reset_usage_count:
|
||||
Dialogs.showSecureDialog(new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.action_reset_usage_count)
|
||||
.setMessage(R.string.action_reset_usage_count_dialog)
|
||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> resetUsageCount())
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.create());
|
||||
break;
|
||||
case R.id.action_default_icon:
|
||||
TextDrawable drawable = TextDrawableHelper.generate(_origEntry.getIssuer(), _origEntry.getName(), _iconView);
|
||||
_iconView.setImageDrawable(drawable);
|
||||
|
@ -431,6 +445,11 @@ public class EditEntryActivity extends AegisActivity {
|
|||
AegisActivity.Helper.startExtActivityForResult(this, chooserIntent, PICK_IMAGE_REQUEST);
|
||||
}
|
||||
|
||||
private void resetUsageCount() {
|
||||
getPreferences().resetUsageCount(_origEntry.getUUID());
|
||||
_textUsageCount.setText("0");
|
||||
}
|
||||
|
||||
private void startIconSelection() {
|
||||
List<IconPack> iconPacks = getApp().getIconPackManager().getIconPacks().stream()
|
||||
.sorted(Comparator.comparing(IconPack::getName))
|
||||
|
|
|
@ -57,6 +57,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -165,6 +166,17 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Map<UUID, Integer> usageMap = _entryListView.getUsageCounts();
|
||||
if (usageMap != null) {
|
||||
getPreferences().setUsageCount(usageMap);
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
_isAuthenticating = false;
|
||||
|
@ -487,6 +499,9 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
// update the list of groups in the entry list view so that the chip gets updated
|
||||
_entryListView.setGroups(_vault.getGroups());
|
||||
|
||||
// update the usage counts in case they are edited outside of the entrylistview
|
||||
_entryListView.setUsageCounts(getPreferences().getUsageCounts());
|
||||
|
||||
// refresh all codes to prevent showing old ones
|
||||
_entryListView.refresh(false);
|
||||
} else {
|
||||
|
@ -605,6 +620,9 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
case R.id.menu_sort_alphabetically_name_reverse:
|
||||
sortCategory = SortCategory.ACCOUNT_REVERSED;
|
||||
break;
|
||||
case R.id.menu_sort_usage_count:
|
||||
sortCategory = SortCategory.USAGE_COUNT;
|
||||
break;
|
||||
case R.id.menu_sort_custom:
|
||||
default:
|
||||
sortCategory = SortCategory.CUSTOM;
|
||||
|
@ -625,6 +643,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
|
||||
private void loadEntries() {
|
||||
if (!_loaded) {
|
||||
_entryListView.setUsageCounts(getPreferences().getUsageCounts());
|
||||
_entryListView.addEntries(_vault.getEntries());
|
||||
_entryListView.runEntriesAnimation();
|
||||
_loaded = true;
|
||||
|
@ -741,6 +760,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
_entryListView.clearEntries();
|
||||
_loaded = false;
|
||||
|
||||
|
||||
if (userInitiated) {
|
||||
startAuthActivity(true);
|
||||
} else {
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.HashSet;
|
|||
|
||||
public class AppearancePreferencesFragment extends PreferencesFragment {
|
||||
private Preference _groupsPreference;
|
||||
private Preference _resetUsageCountPreference;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
|
@ -36,6 +37,17 @@ public class AppearancePreferencesFragment extends PreferencesFragment {
|
|||
return true;
|
||||
});
|
||||
|
||||
_resetUsageCountPreference = findPreference("pref_reset_usage_count");
|
||||
_resetUsageCountPreference.setOnPreferenceClickListener(preference -> {
|
||||
Dialogs.showSecureDialog(new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.preference_reset_usage_count)
|
||||
.setMessage(R.string.preference_reset_usage_count_dialog)
|
||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> getPreferences().clearUsageCount())
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.create());
|
||||
return true;
|
||||
});
|
||||
|
||||
int currentTheme = prefs.getCurrentTheme().ordinal();
|
||||
Preference darkModePreference = findPreference("pref_dark_mode");
|
||||
darkModePreference.setSummary(String.format("%s: %s", getString(R.string.selected), getResources().getStringArray(R.array.theme_titles)[currentTheme]));
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Comparator;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements ItemTouchHelperAdapter {
|
||||
|
@ -32,6 +33,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
private List<VaultEntry> _entries;
|
||||
private List<VaultEntry> _shownEntries;
|
||||
private List<VaultEntry> _selectedEntries;
|
||||
private Map<UUID, Integer> _usageCounts;
|
||||
private VaultEntry _focusedEntry;
|
||||
private int _codeGroupSize;
|
||||
private boolean _showAccountName;
|
||||
|
@ -139,6 +141,10 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
}
|
||||
|
||||
public void addEntries(Collection<VaultEntry> entries) {
|
||||
for (VaultEntry entry: entries) {
|
||||
entry.setUsageCount(_usageCounts.containsKey(entry.getUUID()) ? _usageCounts.get(entry.getUUID()) : 0);
|
||||
}
|
||||
|
||||
_entries.addAll(entries);
|
||||
updateShownEntries();
|
||||
checkPeriodUniformity(true);
|
||||
|
@ -282,6 +288,14 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
_viewMode = viewMode;
|
||||
}
|
||||
|
||||
public void setUsageCounts(Map<UUID, Integer> usageCounts) { _usageCounts = usageCounts; }
|
||||
|
||||
public Map<UUID, Integer> getUsageCounts() { return _usageCounts; }
|
||||
|
||||
public void setGroups(TreeSet<String> groups) {
|
||||
_view.setGroups(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDismiss(int position) {
|
||||
|
||||
|
@ -363,6 +377,8 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
focusEntry(entry, _tapToRevealTime);
|
||||
}
|
||||
}
|
||||
|
||||
incrementUsageCount(entry);
|
||||
} else {
|
||||
if (_selectedEntries.contains(entry)) {
|
||||
_view.onDeselect(entry);
|
||||
|
@ -586,6 +602,15 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
updateDraggableStatus();
|
||||
}
|
||||
|
||||
private void incrementUsageCount(VaultEntry entry) {
|
||||
if (!_usageCounts.containsKey(entry.getUUID())) {
|
||||
_usageCounts.put(entry.getUUID(), 1);
|
||||
} else {
|
||||
int usageCount = _usageCounts.get(entry.getUUID());
|
||||
_usageCounts.put(entry.getUUID(), ++usageCount);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDragAndDropAllowed() {
|
||||
return _sortCategory == SortCategory.CUSTOM && _groupFilter.isEmpty() && _searchFilter == null;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import com.google.android.material.chip.ChipGroup;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -184,6 +185,14 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
}
|
||||
}
|
||||
|
||||
public void setUsageCounts(Map<UUID, Integer> usageCounts) {
|
||||
_adapter.setUsageCounts(usageCounts);
|
||||
}
|
||||
|
||||
public Map<UUID, Integer> getUsageCounts() {
|
||||
return _adapter.getUsageCounts();
|
||||
}
|
||||
|
||||
public void setSearchFilter(String search) {
|
||||
_adapter.setSearchFilter(search);
|
||||
_touchCallback.setIsLongPressDragEnabled(_adapter.isDragAndDropAllowed());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue