Merge branch 'feature-sorting'

This commit is contained in:
Michael Schättgen 2019-03-31 23:30:52 +02:00
commit caf2ec882a
14 changed files with 235 additions and 1 deletions

View file

@ -39,6 +39,15 @@ public class Preferences {
_prefs.edit().putInt("pref_tap_to_reveal_time", number).apply();
}
public void setCurrentSortCategory(SortCategory category) {
_prefs.edit().putInt("pref_current_sort_category", category.ordinal()).apply();
}
public int getCurrentSortCategory() {
return _prefs.getInt("pref_current_sort_category", 0);
}
public int getTapToRevealTime() {
return _prefs.getInt("pref_tap_to_reveal_time", 30);
}

View file

@ -0,0 +1,73 @@
package com.beemdevelopment.aegis;
import com.beemdevelopment.aegis.helpers.comparators.AccountNameComparator;
import com.beemdevelopment.aegis.helpers.comparators.IssuerNameComparator;
import java.util.Comparator;
public enum SortCategory {
CUSTOM,
ACCOUNT,
ACCOUNTREVERSED,
ISSUER,
ISSUERREVERSED;
public static SortCategory fromInteger(int x) {
switch(x) {
case 0:
return CUSTOM;
case 1:
return ACCOUNT;
case 2:
return ACCOUNTREVERSED;
case 3:
return ISSUER;
case 4:
return ISSUERREVERSED;
}
return null;
}
public static Comparator getComparator(SortCategory sortCategory) {
switch(sortCategory) {
case ACCOUNT:
case ACCOUNTREVERSED:
return new AccountNameComparator();
case ISSUER:
case ISSUERREVERSED:
return new IssuerNameComparator();
case CUSTOM:
return new IssuerNameComparator();
}
return null;
}
public static boolean isReversed(SortCategory sortCategory) {
switch(sortCategory) {
case ACCOUNTREVERSED:
case ISSUERREVERSED:
return true;
default:
return false;
}
}
public static int getMenuItem(SortCategory sortCategory) {
switch (sortCategory) {
case CUSTOM:
return R.id.menu_sort_custom;
case ACCOUNT:
return R.id.menu_sort_alphabetically_name;
case ACCOUNTREVERSED:
return R.id.menu_sort_alphabetically_name_reverse;
case ISSUER:
return R.id.menu_sort_alphabetically;
case ISSUERREVERSED:
return R.id.menu_sort_alphabetically_reverse;
default:
return R.id.menu_sort_custom;
}
}
}

View file

@ -0,0 +1,12 @@
package com.beemdevelopment.aegis.helpers.comparators;
import com.beemdevelopment.aegis.db.DatabaseEntry;
import java.util.Comparator;
public class AccountNameComparator implements Comparator<DatabaseEntry> {
@Override
public int compare(DatabaseEntry a, DatabaseEntry b) {
return a.getName().compareToIgnoreCase(b.getName());
}
}

View file

@ -0,0 +1,13 @@
package com.beemdevelopment.aegis.helpers.comparators;
import com.beemdevelopment.aegis.db.DatabaseEntry;
import com.beemdevelopment.aegis.ui.views.EntryHolder;
import java.util.Comparator;
public class IssuerNameComparator implements Comparator<DatabaseEntry> {
@Override
public int compare(DatabaseEntry a, DatabaseEntry b) {
return a.getIssuer().compareToIgnoreCase(b.getIssuer());
}
}

View file

@ -8,6 +8,9 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import com.beemdevelopment.aegis.SortCategory;
import com.beemdevelopment.aegis.helpers.comparators.IssuerNameComparator;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import android.os.Bundle;
import android.view.Menu;
@ -27,6 +30,8 @@ import com.beemdevelopment.aegis.ui.views.EntryListView;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import com.beemdevelopment.aegis.AegisApplication;
@ -55,6 +60,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
private DatabaseManager _db;
private boolean _loaded;
private String _checkedGroup;
private SortCategory _sortCategory;
private Menu _menu;
private FloatingActionsMenu _fabMenu;
@ -257,6 +263,22 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
_entryListView.setGroupFilter(group);
}
private void setSortCategory(SortCategory sortCategory) {
_sortCategory = sortCategory;
if(sortCategory == SortCategory.CUSTOM)
{
_entryListView.clearEntries();
loadEntries();
}
_entryListView.setSortCategory(sortCategory);
}
private void updateSortCategoryMenu(SortCategory sortCategory) {
_menu.findItem(SortCategory.getMenuItem(sortCategory)).setChecked(true);
}
private void addEntry(DatabaseEntry entry) {
_db.addEntry(entry);
_entryListView.addEntry(entry);
@ -398,6 +420,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
updateLockIcon();
if (_loaded) {
updateGroupFilterMenu();
updateSortCategoryMenu(SortCategory.fromInteger(getPreferences().getCurrentSortCategory()));
}
return true;
}
@ -422,6 +445,37 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
}
setGroupFilter(group);
}
if (item.getGroupId() == R.id.action_sort_category) {
item.setChecked(true);
SortCategory sortCategory;
switch (item.getItemId()) {
case R.id.menu_sort_alphabetically:
sortCategory = SortCategory.ISSUER;
break;
case R.id.menu_sort_alphabetically_reverse:
sortCategory = SortCategory.ISSUERREVERSED;
break;
case R.id.menu_sort_alphabetically_name:
sortCategory = SortCategory.ACCOUNT;
break;
case R.id.menu_sort_alphabetically_name_reverse:
sortCategory = SortCategory.ACCOUNTREVERSED;
break;
case R.id.menu_sort_custom:
default:
sortCategory = SortCategory.CUSTOM;
break;
}
setSortCategory(sortCategory);
getPreferences().setCurrentSortCategory(sortCategory);
}
return super.onOptionsItemSelected(item);
}
}
@ -459,11 +513,14 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
}
loadEntries();
SortCategory currentSortCategory = SortCategory.fromInteger(getPreferences().getCurrentSortCategory());
setSortCategory(currentSortCategory);
}
private void loadEntries() {
// load all entries
_entryListView.addEntries(_db.getEntries());
List<DatabaseEntry> entries = new ArrayList<DatabaseEntry>(_db.getEntries());
_entryListView.addEntries(entries);
_loaded = true;
}

View file

@ -5,7 +5,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.beemdevelopment.aegis.SortCategory;
import com.beemdevelopment.aegis.helpers.ItemTouchHelperAdapter;
import com.beemdevelopment.aegis.helpers.comparators.IssuerNameComparator;
import com.beemdevelopment.aegis.otp.HotpInfo;
import com.beemdevelopment.aegis.otp.OtpInfo;
import com.beemdevelopment.aegis.otp.OtpInfoException;
@ -27,6 +29,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
private boolean _tapToReveal;
private int _tapToRevealTime;
private String _groupFilter;
private SortCategory _sortCategory;
// keeps track of the viewholders that are currently bound
private List<EntryHolder> _holders;
@ -151,6 +154,21 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
notifyDataSetChanged();
}
public void setSortCategory(SortCategory sortCategory) {
if (_sortCategory != sortCategory && sortCategory != SortCategory.CUSTOM) {
Collections.sort(_shownEntries, SortCategory.getComparator(sortCategory));
if(SortCategory.isReversed(sortCategory))
{
Collections.reverse(_shownEntries);
}
notifyDataSetChanged();
}
_sortCategory = sortCategory;
}
@Override
public void onItemDismiss(int position) {

View file

@ -14,6 +14,7 @@ import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import com.beemdevelopment.aegis.SortCategory;
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
import com.beemdevelopment.aegis.helpers.UiRefresher;
import com.beemdevelopment.aegis.otp.TotpInfo;
@ -93,6 +94,13 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
runLayoutAnimation(_rvKeyProfiles);
}
public void setSortCategory(SortCategory sortCategory) {
_touchCallback.setIsLongPressDragEnabled(sortCategory == SortCategory.CUSTOM);
_adapter.setSortCategory(sortCategory);
runLayoutAnimation(_rvKeyProfiles);
}
public void refresh(boolean hard) {
if (_showProgress) {
_progressBar.refresh();

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
<path
android:fillColor="#FF000000"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

View file

@ -21,6 +21,35 @@
android:title="@string/all"
android:checked="true" />
</group>
</menu>
</item>
<item
android:id="@+id/action_sort"
android:icon="@drawable/ic_action_sort"
app:showAsAction="always"
android:title="@string/filter">
<menu>
<group
android:id="@+id/action_sort_category"
android:checkableBehavior="single">
<item
android:id="@+id/menu_sort_custom"
android:title="@string/sort_custom"
android:checked="true" />
<item
android:id="@+id/menu_sort_alphabetically_name"
android:title="@string/sort_alphabetically_name"/>
<item
android:id="@+id/menu_sort_alphabetically_name_reverse"
android:title="@string/sort_alphabetically_name_reverse"/>
<item
android:id="@+id/menu_sort_alphabetically"
android:title="@string/sort_alphabetically"/>
<item
android:id="@+id/menu_sort_alphabetically_reverse"
android:title="@string/sort_alphabetically_reverse"/>
</group>
</menu>
</item>
<item

View file

@ -146,6 +146,11 @@
<string name="all">All</string>
<string name="name">Name</string>
<string name="no_group">No group</string>
<string name="sort_alphabetically">Issuer (A to Z)</string>
<string name="sort_alphabetically_reverse">Issuer (Z to A)</string>
<string name="sort_alphabetically_name">Account (A to Z)</string>
<string name="sort_alphabetically_name_reverse">Account (Z to A)</string>
<string name="sort_custom">Custom</string>
<string name="new_group">New group...</string>
<string name="enter_group_name">Enter a group name</string>
<string name="group_name_hint">Group name</string>