Automatic re-hide + sort by last used
* Automatically hide revealed entries after a (configurable) time * Allow sorting of the list by last used Closes #77 Closes #67
This commit is contained in:
parent
d10e4a4e35
commit
4ffe62177f
13 changed files with 301 additions and 47 deletions
|
@ -261,10 +261,10 @@ public class MainActivity extends BaseActivity
|
|||
SortMode mode = settings.getSortMode();
|
||||
adapter.setSortMode(mode);
|
||||
|
||||
if (mode == SortMode.LABEL)
|
||||
touchHelperCallback.setDragEnabled(false);
|
||||
else
|
||||
if (mode == SortMode.UNSORTED)
|
||||
touchHelperCallback.setDragEnabled(true);
|
||||
else
|
||||
touchHelperCallback.setDragEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,12 +431,12 @@ public class MainActivity extends BaseActivity
|
|||
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
if (key.equals(getString(R.string.settings_key_label_size)) ||
|
||||
key.equals(getString(R.string.settings_key_tap_to_reveal)) ||
|
||||
key.equals(getString(R.string.settings_key_label_scroll)) ||
|
||||
key.equals(getString(R.string.settings_key_thumbnail_visible)) ||
|
||||
key.equals(getString(R.string.settings_key_thumbnail_size))) {
|
||||
adapter.notifyDataSetChanged();
|
||||
} else if (key.equals(getString(R.string.settings_key_theme)) ||
|
||||
} else if (key.equals(getString(R.string.settings_key_tap_to_reveal)) ||
|
||||
key.equals(getString(R.string.settings_key_theme)) ||
|
||||
key.equals(getString(R.string.settings_key_lang)) ||
|
||||
key.equals(getString(R.string.settings_key_enable_screenshot))) {
|
||||
recreate();
|
||||
|
@ -503,6 +503,9 @@ public class MainActivity extends BaseActivity
|
|||
} else if (mode == SortMode.LABEL) {
|
||||
sortMenu.setIcon(R.drawable.ic_sort_inverted_label_white);
|
||||
menu.findItem(R.id.menu_sort_label).setChecked(true);
|
||||
} else if (mode == SortMode.LAST_USED) {
|
||||
sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white);
|
||||
menu.findItem(R.id.menu_sort_last_used).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,6 +585,14 @@ public class MainActivity extends BaseActivity
|
|||
adapter.setSortMode(SortMode.LABEL);
|
||||
touchHelperCallback.setDragEnabled(false);
|
||||
}
|
||||
} else if (id == R.id.menu_sort_last_used) {
|
||||
item.setChecked(true);
|
||||
sortMenu.setIcon(R.drawable.ic_sort_inverted_time_white);
|
||||
saveSortMode(SortMode.LAST_USED);
|
||||
if (adapter != null) {
|
||||
adapter.setSortMode(SortMode.LAST_USED);
|
||||
touchHelperCallback.setDragEnabled(false);
|
||||
}
|
||||
} else if (tagsToggle.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ public class SettingsActivity extends BaseActivity
|
|||
case "password":
|
||||
PasswordHashPreference authPassword = new PasswordHashPreference(getActivity(), null);
|
||||
authPassword.setTitle(R.string.settings_title_auth_password);
|
||||
authPassword.setOrder(3);
|
||||
authPassword.setOrder(4);
|
||||
authPassword.setKey(getString(R.string.settings_key_auth_password_hash));
|
||||
authPassword.setMode(PasswordHashPreference.Mode.PASSWORD);
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class SettingsActivity extends BaseActivity
|
|||
case "pin":
|
||||
PasswordHashPreference authPIN = new PasswordHashPreference(getActivity(), null);
|
||||
authPIN.setTitle(R.string.settings_title_auth_pin);
|
||||
authPIN.setOrder(3);
|
||||
authPIN.setOrder(4);
|
||||
authPIN.setKey(getString(R.string.settings_key_auth_pin_hash));
|
||||
authPIN.setMode(PasswordHashPreference.Mode.PIN);
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ public class Entry {
|
|||
private static final String JSON_ALGORITHM = "algorithm";
|
||||
private static final String JSON_TAGS = "tags";
|
||||
private static final String JSON_THUMBNAIL = "thumbnail";
|
||||
private static final String JSON_LAST_USED = "last_used";
|
||||
|
||||
private OTPType type = OTPType.TOTP;
|
||||
private int period = TokenCalculator.TOTP_DEFAULT_PERIOD;
|
||||
|
@ -62,7 +63,10 @@ public class Entry {
|
|||
private byte[] secret;
|
||||
private String label;
|
||||
private String currentOTP;
|
||||
private boolean visible = false;
|
||||
private Runnable hideTask = null;
|
||||
private long last_update = 0;
|
||||
private long last_used = 0;
|
||||
public List<String> tags = new ArrayList<>();
|
||||
private EntryThumbnail.EntryThumbnails thumbnail = EntryThumbnail.EntryThumbnails.Default;
|
||||
|
||||
|
@ -164,7 +168,7 @@ public class Entry {
|
|||
this.tags.add(tagsArray.getString(i));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// Nothing wrong here
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -172,6 +176,12 @@ public class Entry {
|
|||
} catch(Exception e) {
|
||||
this.thumbnail = EntryThumbnail.EntryThumbnails.Default;
|
||||
}
|
||||
|
||||
try {
|
||||
this.last_used = jsonObj.getLong(JSON_LAST_USED);
|
||||
} catch (Exception e) {
|
||||
this.last_used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject toJSON() throws JSONException {
|
||||
|
@ -183,6 +193,7 @@ public class Entry {
|
|||
jsonObj.put(JSON_TYPE, getType().toString());
|
||||
jsonObj.put(JSON_ALGORITHM, algorithm.toString());
|
||||
jsonObj.put(JSON_THUMBNAIL, getThumbnail().name());
|
||||
jsonObj.put(JSON_LAST_USED, getLastUsed());
|
||||
|
||||
JSONArray tagsArray = new JSONArray();
|
||||
for(String tag : tags){
|
||||
|
@ -253,6 +264,30 @@ public class Entry {
|
|||
return this.period != TokenCalculator.TOTP_DEFAULT_PERIOD;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean value) {
|
||||
this.visible = value;
|
||||
}
|
||||
|
||||
public void setHideTask(Runnable newTask) {
|
||||
this.hideTask = newTask;
|
||||
}
|
||||
|
||||
public Runnable getHideTask() {
|
||||
return this.hideTask;
|
||||
}
|
||||
|
||||
public long getLastUsed() {
|
||||
return this.last_used;
|
||||
}
|
||||
|
||||
public void setLastUsed(long value) {
|
||||
this.last_used = value;
|
||||
}
|
||||
|
||||
public String getCurrentOTP() {
|
||||
return currentOTP;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public class Settings {
|
|||
}
|
||||
|
||||
public enum SortMode {
|
||||
UNSORTED, LABEL
|
||||
UNSORTED, LABEL, LAST_USED
|
||||
}
|
||||
|
||||
public Settings(Context context) {
|
||||
|
@ -201,6 +201,10 @@ public class Settings {
|
|||
return getBoolean(R.string.settings_key_tap_to_reveal, false);
|
||||
}
|
||||
|
||||
public int getTapToRevealTimeout() {
|
||||
return getInt(R.string.settings_key_tap_to_reveal_timeout, R.integer.settings_default_tap_to_reveal_timeout);
|
||||
}
|
||||
|
||||
public AuthMethod getAuthMethod() {
|
||||
String authString = getString(R.string.settings_key_auth, R.string.settings_default_auth);
|
||||
return AuthMethod.valueOf(authString.toUpperCase());
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.content.ClipData;
|
|||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
|
@ -67,6 +68,7 @@ import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
|
|||
public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
||||
implements ItemTouchHelperAdapter, Filterable {
|
||||
private Context context;
|
||||
private Handler taskHandler;
|
||||
private EntryFilter filter;
|
||||
private ArrayList<Entry> entries;
|
||||
private ArrayList<Entry> displayedEntries;
|
||||
|
@ -81,6 +83,8 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
this.context = context;
|
||||
this.tagsFilterAdapter = tagsFilterAdapter;
|
||||
this.settings = new Settings(context);
|
||||
this.taskHandler = new Handler();
|
||||
|
||||
loadEntries();
|
||||
}
|
||||
|
||||
|
@ -156,7 +160,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
public void onBindViewHolder(EntryViewHolder entryViewHolder, int i) {
|
||||
Entry entry = displayedEntries.get(i);
|
||||
|
||||
entryViewHolder.updateValues(entry.getLabel(), entry.getCurrentOTP(), entry.getTags(), entry.getThumbnail());
|
||||
entryViewHolder.updateValues(entry.getLabel(), entry.getCurrentOTP(), entry.getTags(), entry.getThumbnail(), entry.isVisible());
|
||||
|
||||
if (entry.hasNonDefaultPeriod()) {
|
||||
entryViewHolder.showCustomPeriod(entry.getPeriod());
|
||||
|
@ -164,12 +168,6 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
entryViewHolder.hideCustomPeriod();
|
||||
}
|
||||
|
||||
if (settings.getTapToReveal()) {
|
||||
entryViewHolder.enableTapToReveal();
|
||||
} else {
|
||||
entryViewHolder.disableTapToReveal();
|
||||
}
|
||||
|
||||
entryViewHolder.setLabelSize(settings.getLabelSize());
|
||||
entryViewHolder.setThumbnailSize(settings.getThumbnailSize());
|
||||
entryViewHolder.setLabelScroll(settings.getScrollLabel());
|
||||
|
@ -179,7 +177,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
public EntryViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.component_card, viewGroup, false);
|
||||
|
||||
EntryViewHolder viewHolder = new EntryViewHolder(context, itemView);
|
||||
EntryViewHolder viewHolder = new EntryViewHolder(context, itemView, settings.getTapToReveal());
|
||||
viewHolder.setCallback(new EntryViewHolder.Callback() {
|
||||
@Override
|
||||
public void onMoveEventStart() {
|
||||
|
@ -199,14 +197,76 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCopyButtonClicked(String text) {
|
||||
public void onCopyButtonClicked(String text, int position) {
|
||||
copyToClipboard(text);
|
||||
updateLastUsed(position, getRealIndex(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTap(final int position) {
|
||||
if (settings.getTapToReveal()) {
|
||||
final Entry entry = displayedEntries.get(position);
|
||||
final int realIndex = entries.indexOf(entry);
|
||||
|
||||
if (entry.isVisible()) {
|
||||
hideEntry(entry);
|
||||
} else {
|
||||
entries.get(realIndex).setHideTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideEntry(entry);
|
||||
}
|
||||
});
|
||||
taskHandler.postDelayed(entries.get(realIndex).getHideTask(), settings.getTapToRevealTimeout() * 1000);
|
||||
|
||||
entry.setVisible(true);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
private void hideEntry(Entry entry) {
|
||||
int pos = displayedEntries.indexOf(entry);
|
||||
int realIndex = entries.indexOf(entry);
|
||||
|
||||
if (realIndex >= 0) {
|
||||
entries.get(realIndex).setVisible(false);
|
||||
taskHandler.removeCallbacks(entries.get(realIndex).getHideTask());
|
||||
entries.get(realIndex).setHideTask(null);
|
||||
}
|
||||
|
||||
boolean updateNeeded = updateLastUsed(pos, realIndex);
|
||||
|
||||
if (pos >= 0) {
|
||||
displayedEntries.get(pos).setVisible(false);
|
||||
|
||||
if (updateNeeded)
|
||||
notifyItemChanged(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateLastUsed(int position, int realIndex) {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
|
||||
if (position >= 0)
|
||||
displayedEntries.get(position).setLastUsed(timeStamp);
|
||||
|
||||
entries.get(realIndex).setLastUsed(timeStamp);
|
||||
DatabaseHelper.saveDatabase(context, entries);
|
||||
|
||||
if (sortMode == SortMode.LAST_USED) {
|
||||
displayedEntries = sortEntries(displayedEntries);
|
||||
notifyDataSetChanged();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemMove(int fromPosition, int toPosition) {
|
||||
if (sortMode == SortMode.UNSORTED && displayedEntries.equals(entries)) {
|
||||
|
@ -469,6 +529,8 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
|
||||
if (sortMode == SortMode.LABEL) {
|
||||
Collections.sort(sorted, new LabelComparator());
|
||||
} else if (sortMode == SortMode.LAST_USED) {
|
||||
Collections.sort(sorted, new LastUsedComparator());
|
||||
}
|
||||
|
||||
return sorted;
|
||||
|
@ -538,6 +600,13 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
}
|
||||
}
|
||||
|
||||
public class LastUsedComparator implements Comparator<Entry> {
|
||||
@Override
|
||||
public int compare(Entry o1, Entry o2) {
|
||||
return Long.compare(o2.getLastUsed(), o1.getLastUsed());
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onMoveEventStart();
|
||||
void onMoveEventStop();
|
||||
|
|
|
@ -45,8 +45,8 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
implements ItemTouchHelperViewHolder {
|
||||
|
||||
private Context context;
|
||||
|
||||
private Callback callback;
|
||||
private boolean tapToReveal;
|
||||
|
||||
private CardView card;
|
||||
private LinearLayout valueLayout;
|
||||
|
@ -59,10 +59,11 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
private TextView tags;
|
||||
private TextView customPeriod;
|
||||
|
||||
public EntryViewHolder(Context context, final View v) {
|
||||
public EntryViewHolder(Context context, final View v, boolean tapToReveal) {
|
||||
super(v);
|
||||
|
||||
this.context = context;
|
||||
this.tapToReveal = tapToReveal;
|
||||
|
||||
card = v.findViewById(R.id.card_view);
|
||||
value = v.findViewById(R.id.valueText);
|
||||
|
@ -100,12 +101,14 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
if (callback != null)
|
||||
callback.onCopyButtonClicked(value.getText().toString());
|
||||
callback.onCopyButtonClicked(value.getText().toString(), getAdapterPosition());
|
||||
}
|
||||
});
|
||||
|
||||
setTapToReveal(tapToReveal);
|
||||
}
|
||||
|
||||
public void updateValues(String label, String token, List<String> tags, EntryThumbnail.EntryThumbnails thumbnail) {
|
||||
public void updateValues(String label, String token, List<String> tags, EntryThumbnail.EntryThumbnails thumbnail, boolean isVisible) {
|
||||
Settings settings = new Settings(context);
|
||||
|
||||
this.label.setText(label);
|
||||
|
@ -130,6 +133,18 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
|
||||
int thumbnailSize = settings.getThumbnailSize();
|
||||
thumbnailImg.setImageBitmap(EntryThumbnail.getThumbnailGraphic(context, label, thumbnailSize, thumbnail));
|
||||
|
||||
if (this.tapToReveal) {
|
||||
if (isVisible) {
|
||||
valueLayout.setVisibility(View.VISIBLE);
|
||||
coverLayout.setVisibility(View.GONE);
|
||||
visibleImg.setVisibility(View.GONE);
|
||||
} else {
|
||||
valueLayout.setVisibility(View.GONE);
|
||||
coverLayout.setVisibility(View.VISIBLE);
|
||||
visibleImg.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showCustomPeriod(int period) {
|
||||
|
@ -164,31 +179,25 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
}
|
||||
}
|
||||
|
||||
public void enableTapToReveal() {
|
||||
valueLayout.setVisibility(View.GONE);
|
||||
coverLayout.setVisibility(View.VISIBLE);
|
||||
visibleImg.setVisibility(View.VISIBLE);
|
||||
private void setTapToReveal(boolean enabled) {
|
||||
if (enabled) {
|
||||
valueLayout.setVisibility(View.GONE);
|
||||
coverLayout.setVisibility(View.VISIBLE);
|
||||
visibleImg.setVisibility(View.VISIBLE);
|
||||
|
||||
card.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (valueLayout.getVisibility() == View.GONE && coverLayout.getVisibility() == View.VISIBLE) {
|
||||
valueLayout.setVisibility(View.VISIBLE);
|
||||
coverLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
valueLayout.setVisibility(View.GONE);
|
||||
coverLayout.setVisibility(View.VISIBLE);
|
||||
card.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
callback.onTap(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
valueLayout.setVisibility(View.VISIBLE);
|
||||
coverLayout.setVisibility(View.GONE);
|
||||
visibleImg.setVisibility(View.GONE);
|
||||
|
||||
public void disableTapToReveal() {
|
||||
valueLayout.setVisibility(View.VISIBLE);
|
||||
coverLayout.setVisibility(View.GONE);
|
||||
visibleImg.setVisibility(View.GONE);
|
||||
|
||||
card.setOnClickListener(null);
|
||||
card.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -212,6 +221,7 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
void onMoveEventStop();
|
||||
|
||||
void onMenuButtonClicked(View parentView, int position);
|
||||
void onCopyButtonClicked(String text);
|
||||
void onCopyButtonClicked(String text, int position);
|
||||
void onTap(int position);
|
||||
}
|
||||
}
|
||||
|
|
24
app/src/main/res/drawable/ic_sort_inverted_time_white.xml
Normal file
24
app/src/main/res/drawable/ic_sort_inverted_time_white.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:pathData="m21,18h-6v-2h6zM21,6L21,8L3,8L3,6ZM21,13L9,13v-2h12z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M5.416,18.479m-4.491,0a4.491,4.491 0,1 1,8.981 0a4.491,4.491 0,1 1,-8.981 0"
|
||||
android:fillAlpha="1"
|
||||
android:strokeColor="#FFFFFF"
|
||||
android:fillColor="#00FFFFFF"
|
||||
android:strokeWidth="1.29999995"
|
||||
android:strokeAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m5.416,15.909v2.57l2.44,2.404"
|
||||
android:strokeLineCap="butt"
|
||||
android:strokeColor="#FFFFFF"
|
||||
android:fillColor="#00FFFFFF"
|
||||
android:strokeWidth="0.9"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeAlpha="1"/>
|
||||
</vector>
|
|
@ -17,6 +17,10 @@
|
|||
<item
|
||||
android:id="@+id/menu_sort_label"
|
||||
android:title="@string/menu_sort_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_sort_last_used"
|
||||
android:title="@string/menu_sort_last_used" />
|
||||
</group>
|
||||
</menu>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<string name="settings_key_cat_security" translatable="false">pref_cat_security</string>
|
||||
|
||||
<string name="settings_key_tap_to_reveal" translatable="false">pref_tap_to_reveal</string>
|
||||
<string name="settings_key_tap_to_reveal_timeout" translatable="false">pref_tap_to_reveal_timeout</string>
|
||||
<string name="settings_key_auth" translatable="false">pref_auth</string>
|
||||
<string name="settings_key_auth_password" translatable="false">pref_auth_password</string>
|
||||
<string name="settings_key_auth_password_hash" translatable="false">pref_auth_password_hash</string>
|
||||
|
@ -37,6 +38,7 @@
|
|||
<string name="settings_key_enable_screenshot" translatable="false">pref_enable_screenshot</string>
|
||||
|
||||
<!-- Default values -->
|
||||
<integer name="settings_default_tap_to_reveal_timeout">30</integer>
|
||||
<string name="settings_default_auth" translatable="false">none</string>
|
||||
<string name="settings_default_lang" translatable="false">system</string>
|
||||
<string name="settings_default_theme" translatable="false">light</string>
|
||||
|
@ -99,6 +101,8 @@
|
|||
</string-array>
|
||||
|
||||
<!-- Constraints -->
|
||||
<integer name="settings_min_tap_to_reveal_timeout">5</integer>
|
||||
<integer name="settings_max_tap_to_reveal_timeout">60</integer>
|
||||
<integer name="settings_min_label_size">12</integer>
|
||||
<integer name="settings_max_label_size">24</integer>
|
||||
</resources>
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
<string name="menu_sort_none">Unsorted</string>
|
||||
<string name="menu_sort_label">Label</string>
|
||||
<string name="menu_sort_last_used">Last used</string>
|
||||
|
||||
<string name="menu_popup_edit_label">Edit label</string>
|
||||
<string name="menu_popup_change_image">Change image</string>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
<!-- Titles -->
|
||||
<string name="settings_title_tap_to_reveal">Tap to reveal</string>
|
||||
<string name="settings_title_tap_to_reveal_timeout">Timeout for tap to reveal</string>
|
||||
<string name="settings_title_auth">Authentication</string>
|
||||
<string name="settings_title_auth_password">Password</string>
|
||||
<string name="settings_title_auth_pin">PIN</string>
|
||||
|
@ -35,6 +36,8 @@
|
|||
<!-- Descriptions -->
|
||||
<string name="settings_desc_tap_to_reveal">Hide the OTP tokens by default, requiring them to be
|
||||
revealed manually</string>
|
||||
<string name="settings_desc_tap_to_reveal_timeout">Select the time (in sec) after which to hide
|
||||
revealed entries again</string>
|
||||
<string name="settings_desc_panic">Decide what happens when a Panic Trigger is received</string>
|
||||
|
||||
<string name="settings_desc_label_scroll">Scroll overlong labels instead of truncating them</string>
|
||||
|
|
|
@ -14,9 +14,19 @@
|
|||
android:summary="@string/settings_desc_tap_to_reveal"
|
||||
android:defaultValue="false" />
|
||||
|
||||
<com.vanniktech.vntnumberpickerpreference.VNTNumberPickerPreference
|
||||
android:key="@string/settings_key_tap_to_reveal_timeout"
|
||||
android:order="2"
|
||||
android:title="@string/settings_title_tap_to_reveal_timeout"
|
||||
android:dialogMessage="@string/settings_desc_tap_to_reveal_timeout"
|
||||
android:defaultValue="@integer/settings_default_tap_to_reveal_timeout"
|
||||
android:dependency="@string/settings_key_tap_to_reveal"
|
||||
app:vnt_minValue="@integer/settings_min_tap_to_reveal_timeout"
|
||||
app:vnt_maxValue="@integer/settings_max_tap_to_reveal_timeout" />
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/settings_key_auth"
|
||||
android:order="2"
|
||||
android:order="3"
|
||||
android:title="@string/settings_title_auth"
|
||||
android:summary="%s"
|
||||
android:entries="@array/settings_entries_auth"
|
||||
|
@ -25,7 +35,7 @@
|
|||
|
||||
<MultiSelectListPreference
|
||||
android:key="@string/settings_key_panic"
|
||||
android:order="4"
|
||||
android:order="5"
|
||||
android:title="@string/settings_title_panic"
|
||||
android:summary="@string/settings_desc_panic"
|
||||
android:entries="@array/settings_entries_panic"
|
||||
|
|
79
assets/icons/ic_sort_inverted_time.svg
Normal file
79
assets/icons/ic_sort_inverted_time.svg
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
fill="#000000"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
version="1.1"
|
||||
id="svg6"
|
||||
sodipodi:docname="ic_sort_inverted_time.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="27.812866"
|
||||
inkscape:cx="11.117825"
|
||||
inkscape:cy="9.3826625"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="31"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g824"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true" />
|
||||
<path
|
||||
d="m 21,18 h -6 v -2 h 6 z M 21,6 V 8 H 3 V 6 Z m 0,7 H 9 v -2 h 12 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"
|
||||
id="path4" />
|
||||
<g
|
||||
id="g824"
|
||||
transform="translate(-0.79100081,-18.552564)">
|
||||
<circle
|
||||
r="4.4905343"
|
||||
cy="37.03157"
|
||||
cx="6.2066832"
|
||||
id="path815"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.29999995;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 6.2066825,34.461271 v 2.570305 l 2.4398741,2.40392"
|
||||
id="path845"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in a new issue