Merge pull request #467 from Ullas-Aithal/feature/443

Added 'Most Used' sort option #443
This commit is contained in:
Jakob Nixdorf 2020-02-04 07:45:15 +01:00 committed by GitHub
commit b2b8b582bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 84 additions and 5 deletions

View file

@ -512,6 +512,9 @@ public class MainActivity extends BaseActivity
} else if (mode == SortMode.LAST_USED) { } else if (mode == SortMode.LAST_USED) {
sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white); sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white);
menu.findItem(R.id.menu_sort_last_used).setChecked(true); menu.findItem(R.id.menu_sort_last_used).setChecked(true);
} else if (mode == SortMode.MOST_USED) {
sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white);
menu.findItem(R.id.menu_sort_most_used).setChecked(true);
} }
} }
@ -609,6 +612,16 @@ public class MainActivity extends BaseActivity
} }
if (! settings.getLastUsedDialogShown()) if (! settings.getLastUsedDialogShown())
showLastUsedDialog(); showLastUsedDialog();
} else if (id == R.id.menu_sort_most_used) {
item.setChecked(true);
sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white);
saveSortMode(SortMode.MOST_USED);
if (adapter != null) {
adapter.setSortMode(SortMode.MOST_USED);
touchHelperCallback.setDragEnabled(false);
}
if (! settings.getMostUsedDialogShown())
showMostUsedDialog();
} else if (tagsToggle.onOptionsItemSelected(item)) { } else if (tagsToggle.onOptionsItemSelected(item)) {
return true; return true;
} }
@ -630,6 +643,20 @@ public class MainActivity extends BaseActivity
.create() .create()
.show(); .show();
} }
private void showMostUsedDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dialog_title_manual_entry)
.setTitle(R.string.dialog_title_most_used)
.setMessage(R.string.dialog_msg_most_used)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
settings.setMostUsedDialogShown(true);
}
})
.create()
.show();
}
private void setupDrawer() { private void setupDrawer() {
tagsDrawerListView = findViewById(R.id.tags_list_in_drawer); tagsDrawerListView = findViewById(R.id.tags_list_in_drawer);

View file

@ -60,6 +60,7 @@ public class Entry {
private static final String JSON_TAGS = "tags"; private static final String JSON_TAGS = "tags";
private static final String JSON_THUMBNAIL = "thumbnail"; private static final String JSON_THUMBNAIL = "thumbnail";
private static final String JSON_LAST_USED = "last_used"; private static final String JSON_LAST_USED = "last_used";
private static final String JSON_USED_FREQUENCY = "used_frequency";
private OTPType type = OTPType.TOTP; private OTPType type = OTPType.TOTP;
private int period = TokenCalculator.TOTP_DEFAULT_PERIOD; private int period = TokenCalculator.TOTP_DEFAULT_PERIOD;
@ -74,6 +75,7 @@ public class Entry {
private Runnable hideTask = null; private Runnable hideTask = null;
private long last_update = 0; private long last_update = 0;
private long last_used = 0; private long last_used = 0;
private long used_frequency = 0;
public List<String> tags = new ArrayList<>(); public List<String> tags = new ArrayList<>();
private EntryThumbnail.EntryThumbnails thumbnail = EntryThumbnail.EntryThumbnails.Default; private EntryThumbnail.EntryThumbnails thumbnail = EntryThumbnail.EntryThumbnails.Default;
private static final int COLOR_DEFAULT = 0; private static final int COLOR_DEFAULT = 0;
@ -240,6 +242,12 @@ public class Entry {
} catch (Exception e) { } catch (Exception e) {
this.last_used = 0; this.last_used = 0;
} }
try {
this.used_frequency = jsonObj.getLong(JSON_USED_FREQUENCY);
} catch (Exception e) {
this.used_frequency = 0;
}
} }
public JSONObject toJSON() throws JSONException { public JSONObject toJSON() throws JSONException {
@ -252,6 +260,7 @@ public class Entry {
jsonObj.put(JSON_ALGORITHM, algorithm.toString()); jsonObj.put(JSON_ALGORITHM, algorithm.toString());
jsonObj.put(JSON_THUMBNAIL, getThumbnail().name()); jsonObj.put(JSON_THUMBNAIL, getThumbnail().name());
jsonObj.put(JSON_LAST_USED, getLastUsed()); jsonObj.put(JSON_LAST_USED, getLastUsed());
jsonObj.put(JSON_USED_FREQUENCY, getUsedFrequency() );
if (type == OTPType.TOTP) if (type == OTPType.TOTP)
jsonObj.put(JSON_PERIOD, getPeriod()); jsonObj.put(JSON_PERIOD, getPeriod());
@ -373,6 +382,14 @@ public class Entry {
this.last_used = value; this.last_used = value;
} }
public long getUsedFrequency() {
return used_frequency;
}
public void setUsedFrequency(long value) {
this.used_frequency = value;
}
public String getCurrentOTP() { public String getCurrentOTP() {
return currentOTP; return currentOTP;
} }

View file

@ -37,7 +37,7 @@ public class Constants {
} }
public enum SortMode { public enum SortMode {
UNSORTED, LABEL, LAST_USED UNSORTED, LABEL, LAST_USED, MOST_USED
} }
public enum BackupType { public enum BackupType {

View file

@ -530,6 +530,13 @@ public class Settings {
public void setLastUsedDialogShown(boolean value) { public void setLastUsedDialogShown(boolean value) {
setBoolean(R.string.settings_key_last_used_dialog_shown, value); setBoolean(R.string.settings_key_last_used_dialog_shown, value);
} }
public boolean getMostUsedDialogShown() {
return getBoolean(R.string.settings_key_most_used_dialog_shown, false);
}
public void setMostUsedDialogShown(boolean value) {
setBoolean(R.string.settings_key_most_used_dialog_shown, value);
}
public boolean getNewBackupFormatDialogShown() { public boolean getNewBackupFormatDialogShown() {
return getBoolean(R.string.settings_key_new_backup_format_dialog_shown, false); return getBoolean(R.string.settings_key_new_backup_format_dialog_shown, false);

View file

@ -270,7 +270,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
@Override @Override
public void onCopyButtonClicked(String text, int position) { public void onCopyButtonClicked(String text, int position) {
copyToClipboard(text); copyToClipboard(text);
updateLastUsed(position, getRealIndex(position)); updateLastUsedAndFrequency(position, getRealIndex(position));
if(context != null && settings.isMinimizeAppOnCopyEnabled()) { if(context != null && settings.isMinimizeAppOnCopyEnabled()) {
((MainActivity)context).moveTaskToBack(true); ((MainActivity)context).moveTaskToBack(true);
} }
@ -339,7 +339,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
entries.get(realIndex).setHideTask(null); entries.get(realIndex).setHideTask(null);
} }
boolean updateNeeded = updateLastUsed(pos, realIndex); boolean updateNeeded = updateLastUsedAndFrequency(pos, realIndex);
if (pos >= 0) { if (pos >= 0) {
displayedEntries.get(pos).setVisible(false); displayedEntries.get(pos).setVisible(false);
@ -390,19 +390,28 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
.show(); .show();
} }
private boolean updateLastUsed(int position, int realIndex) { private boolean updateLastUsedAndFrequency(int position, int realIndex) {
long timeStamp = System.currentTimeMillis(); long timeStamp = System.currentTimeMillis();
long entryUsedFrequency = entries.get(realIndex).getUsedFrequency();
if (position >= 0) if (position >= 0) {
long displayEntryUsedFrequency = displayedEntries.get(position).getUsedFrequency();
displayedEntries.get(position).setLastUsed(timeStamp); displayedEntries.get(position).setLastUsed(timeStamp);
displayedEntries.get(position).setUsedFrequency(displayEntryUsedFrequency + 1);
}
entries.get(realIndex).setLastUsed(timeStamp); entries.get(realIndex).setLastUsed(timeStamp);
entries.get(realIndex).setUsedFrequency(entryUsedFrequency + 1);
saveEntries(settings.getAutoBackupEncryptedFullEnabled()); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
if (sortMode == SortMode.LAST_USED) { if (sortMode == SortMode.LAST_USED) {
displayedEntries = sortEntries(displayedEntries); displayedEntries = sortEntries(displayedEntries);
notifyDataSetChanged(); notifyDataSetChanged();
return false; return false;
} else if (sortMode == SortMode.MOST_USED) {
displayedEntries = sortEntries(displayedEntries);
notifyDataSetChanged();
return false;
} }
return true; return true;
@ -728,6 +737,8 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
Collections.sort(sorted, new LabelComparator()); Collections.sort(sorted, new LabelComparator());
} else if (sortMode == SortMode.LAST_USED) { } else if (sortMode == SortMode.LAST_USED) {
Collections.sort(sorted, new LastUsedComparator()); Collections.sort(sorted, new LastUsedComparator());
} else if (sortMode == SortMode.MOST_USED) {
Collections.sort(sorted, new MostUsedComparator());
} }
return sorted; return sorted;
@ -822,6 +833,13 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
} }
} }
public class MostUsedComparator implements Comparator<Entry> {
@Override
public int compare(Entry o1, Entry o2) {
return Long.compare(o2.getUsedFrequency(), o1.getUsedFrequency());
}
}
public interface Callback { public interface Callback {
void onMoveEventStart(); void onMoveEventStart();
void onMoveEventStop(); void onMoveEventStop();

View file

@ -21,6 +21,9 @@
<item <item
android:id="@+id/menu_sort_last_used" android:id="@+id/menu_sort_last_used"
android:title="@string/menu_sort_last_used" /> android:title="@string/menu_sort_last_used" />
<item
android:id="@+id/menu_sort_most_used"
android:title="@string/menu_sort_most_used" />
</group> </group>
</menu> </menu>

View file

@ -60,6 +60,7 @@
<string name="settings_key_clear_keystore" translatable="false">pref_clear_keystore</string> <string name="settings_key_clear_keystore" translatable="false">pref_clear_keystore</string>
<string name="settings_key_last_used_dialog_shown" translatable="false">pref_last_used_dialog_shown</string> <string name="settings_key_last_used_dialog_shown" translatable="false">pref_last_used_dialog_shown</string>
<string name="settings_key_most_used_dialog_shown" translatable="false">pref_most_used_dialog_shown</string>
<!-- Default values --> <!-- Default values -->
<integer name="settings_default_tap_to_reveal_timeout">30</integer> <integer name="settings_default_tap_to_reveal_timeout">30</integer>

View file

@ -49,6 +49,7 @@
<string name="menu_sort_none">Unsorted</string> <string name="menu_sort_none">Unsorted</string>
<string name="menu_sort_label">Label</string> <string name="menu_sort_label">Label</string>
<string name="menu_sort_last_used">Last used</string> <string name="menu_sort_last_used">Last used</string>
<string name="menu_sort_most_used">Most used</string>
<string name="menu_popup_edit_issuer">Edit issuer</string> <string name="menu_popup_edit_issuer">Edit issuer</string>
<string name="menu_popup_edit_label">Edit label</string> <string name="menu_popup_edit_label">Edit label</string>
@ -77,6 +78,7 @@
<string name="dialog_title_rename">Rename</string> <string name="dialog_title_rename">Rename</string>
<string name="dialog_title_counter">Counter</string> <string name="dialog_title_counter">Counter</string>
<string name="dialog_title_last_used">Last used</string> <string name="dialog_title_last_used">Last used</string>
<string name="dialog_title_most_used">Most used</string>
<string name="dialog_title_keystore_error">KeyStore error</string> <string name="dialog_title_keystore_error">KeyStore error</string>
<string name="dialog_title_enter_password">Enter password</string> <string name="dialog_title_enter_password">Enter password</string>
@ -91,6 +93,10 @@
you have to have \"tap to reveal\" enabled or use the copy button.\n\nThis message will not you have to have \"tap to reveal\" enabled or use the copy button.\n\nThis message will not
be shown again.</string> be shown again.</string>
<string name="dialog_msg_most_used">In order for andOTP to recognize which token was used the most
you have to have \"tap to reveal\" enabled or use the copy button.\n\nThis message will not
be shown again.</string>
<string name="dialog_msg_keystore_error">Failed to load the encryption key from the KeyStore. <string name="dialog_msg_keystore_error">Failed to load the encryption key from the KeyStore.
<b>Any entries that are added will get lost.</b>\n\nTo still be able to use andOTP you can go <b>Any entries that are added will get lost.</b>\n\nTo still be able to use andOTP you can go
to the <b>Settings</b> and switch the <b>Database encryption</b> to <b>Password / PIN</b>.</string> to the <b>Settings</b> and switch the <b>Database encryption</b> to <b>Password / PIN</b>.</string>