parent
aea7fa6964
commit
8107256cde
11 changed files with 195 additions and 93 deletions
|
@ -491,7 +491,8 @@ public class MainActivity extends BaseActivity
|
|||
key.equals(getString(R.string.settings_key_theme_mode)) ||
|
||||
key.equals(getString(R.string.settings_key_theme_black_auto)) ||
|
||||
key.equals(getString(R.string.settings_key_hide_global_timeout)) ||
|
||||
key.equals(getString(R.string.settings_key_hide_issuer))) {
|
||||
key.equals(getString(R.string.settings_key_hide_issuer)) ||
|
||||
key.equals(getString(R.string.settings_key_show_prev_token))) {
|
||||
recreateActivity = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ public class Entry {
|
|||
private String issuer;
|
||||
private String label;
|
||||
private String currentOTP;
|
||||
private String prevOTP;
|
||||
private boolean visible = false;
|
||||
private Runnable hideTask = null;
|
||||
private long last_update = 0;
|
||||
|
@ -150,7 +151,12 @@ public class Entry {
|
|||
|
||||
String counter = uri.getQueryParameter("counter");
|
||||
String issuer = uri.getQueryParameter("issuer");
|
||||
String label = getStrippedLabel(issuer, uri.getPath().substring(1));
|
||||
|
||||
String label = "";
|
||||
|
||||
if (uri.getPath() != null)
|
||||
label = getStrippedLabel(issuer, uri.getPath().substring(1));
|
||||
|
||||
String period = uri.getQueryParameter("period");
|
||||
String digits = uri.getQueryParameter("digits");
|
||||
String algorithm = uri.getQueryParameter("algorithm");
|
||||
|
@ -172,6 +178,10 @@ public class Entry {
|
|||
|
||||
this.issuer = issuer;
|
||||
this.label = label;
|
||||
|
||||
if (secret == null)
|
||||
throw new Exception("Empty secret");
|
||||
|
||||
if(type == OTPType.MOTP) {
|
||||
this.secret = secret.getBytes();
|
||||
} else {
|
||||
|
@ -475,6 +485,10 @@ public class Entry {
|
|||
return currentOTP;
|
||||
}
|
||||
|
||||
public String getPrevOTP() {
|
||||
return prevOTP;
|
||||
}
|
||||
|
||||
public String getPin() {
|
||||
return pin;
|
||||
}
|
||||
|
@ -492,18 +506,48 @@ public class Entry {
|
|||
}
|
||||
|
||||
public boolean updateOTP(boolean updateNow) {
|
||||
if (type == OTPType.TOTP || type == OTPType.STEAM) {
|
||||
if (type == OTPType.TOTP || type == OTPType.STEAM || type == OTPType.MOTP) {
|
||||
long time = System.currentTimeMillis() / 1000;
|
||||
long counter = time / this.getPeriod();
|
||||
|
||||
if (updateNow || counter > last_update) {
|
||||
if (type == OTPType.TOTP)
|
||||
currentOTP = TokenCalculator.TOTP_RFC6238(secret, period, digits, algorithm);
|
||||
else if (type == OTPType.STEAM)
|
||||
currentOTP = TokenCalculator.TOTP_Steam(secret, period, digits, algorithm);
|
||||
// Store the previous token so we don't have to recalculate it every time
|
||||
if (currentOTP != null && !currentOTP.isEmpty())
|
||||
prevOTP = currentOTP;
|
||||
else
|
||||
prevOTP = "";
|
||||
|
||||
switch (type) {
|
||||
case TOTP:
|
||||
currentOTP = TokenCalculator.TOTP_RFC6238(secret, period, digits, algorithm, 0);
|
||||
|
||||
if (prevOTP == null || prevOTP.isEmpty())
|
||||
prevOTP = TokenCalculator.TOTP_RFC6238(secret, period, digits, algorithm, -1);
|
||||
|
||||
break;
|
||||
case STEAM:
|
||||
currentOTP = TokenCalculator.TOTP_Steam(secret, period, digits, algorithm, 0);
|
||||
|
||||
if (prevOTP == null || prevOTP.isEmpty())
|
||||
prevOTP = TokenCalculator.TOTP_Steam(secret, period, digits, algorithm, -1);
|
||||
|
||||
break;
|
||||
case MOTP:
|
||||
String currentPin = this.getPin();
|
||||
|
||||
if (currentPin.isEmpty()) {
|
||||
currentOTP = MOTP_NO_PIN_CODE;
|
||||
} else {
|
||||
currentOTP = TokenCalculator.MOTP(currentPin, new String(this.secret), time, 0);
|
||||
|
||||
if (prevOTP == null || prevOTP.isEmpty())
|
||||
prevOTP = TokenCalculator.MOTP(currentPin, new String(this.secret), time, -1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
last_update = counter;
|
||||
//New OTP. Change color to default color
|
||||
setColor(COLOR_DEFAULT);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -512,22 +556,6 @@ public class Entry {
|
|||
} else if (type == OTPType.HOTP) {
|
||||
currentOTP = TokenCalculator.HOTP(secret, counter, digits, algorithm);
|
||||
return true;
|
||||
} else if (type == OTPType.MOTP) {
|
||||
long time = System.currentTimeMillis() / 1000;
|
||||
long counter = time / this.getPeriod();
|
||||
if (counter > last_update || updateNow) {
|
||||
String currentPin = this.getPin();
|
||||
if (currentPin.isEmpty()) {
|
||||
currentOTP = MOTP_NO_PIN_CODE;
|
||||
} else {
|
||||
currentOTP = TokenCalculator.MOTP(currentPin, new String(this.secret), time);
|
||||
}
|
||||
last_update = counter;
|
||||
setColor(COLOR_DEFAULT);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -675,4 +675,8 @@ public class Settings {
|
|||
String labelDisplay = getString(R.string.settings_key_label_display, R.string.settings_default_label_display);
|
||||
return Constants.LabelDisplay.valueOf(labelDisplay.toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public boolean getShowPrevToken() {
|
||||
return getBoolean(R.string.settings_key_show_prev_token, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,19 +61,24 @@ public class TokenCalculator {
|
|||
return mac.doFinal(data);
|
||||
}
|
||||
|
||||
// TODO: Rewrite tests so this compatibility wrapper can be removed
|
||||
public static int TOTP_RFC6238(byte[] secret, int period, long time, int digits, HashAlgorithm algorithm) {
|
||||
int fullToken = TOTP(secret, period, time, algorithm);
|
||||
return TOTP_RFC6238(secret, period, time, digits, algorithm, 0);
|
||||
}
|
||||
|
||||
public static int TOTP_RFC6238(byte[] secret, int period, long time, int digits, HashAlgorithm algorithm, int offset) {
|
||||
int fullToken = TOTP(secret, period, time, algorithm, offset);
|
||||
int div = (int) Math.pow(10, digits);
|
||||
|
||||
return fullToken % div;
|
||||
}
|
||||
|
||||
public static String TOTP_RFC6238(byte[] secret, int period, int digits, HashAlgorithm algorithm) {
|
||||
return Tools.formatTokenString(TOTP_RFC6238(secret, period, System.currentTimeMillis() / 1000, digits, algorithm), digits);
|
||||
public static String TOTP_RFC6238(byte[] secret, int period, int digits, HashAlgorithm algorithm, int offset) {
|
||||
return Tools.formatTokenString(TOTP_RFC6238(secret, period, System.currentTimeMillis() / 1000, digits, algorithm, offset), digits);
|
||||
}
|
||||
|
||||
public static String TOTP_Steam(byte[] secret, int period, int digits, HashAlgorithm algorithm) {
|
||||
int fullToken = TOTP(secret, period, System.currentTimeMillis() / 1000, algorithm);
|
||||
public static String TOTP_Steam(byte[] secret, int period, int digits, HashAlgorithm algorithm, int offset) {
|
||||
int fullToken = TOTP(secret, period, System.currentTimeMillis() / 1000, algorithm, offset);
|
||||
|
||||
StringBuilder tokenBuilder = new StringBuilder();
|
||||
|
||||
|
@ -92,8 +97,8 @@ public class TokenCalculator {
|
|||
return Tools.formatTokenString(fullToken % div, digits);
|
||||
}
|
||||
|
||||
private static int TOTP(byte[] key, int period, long time, HashAlgorithm algorithm) {
|
||||
return HOTP(key, time / period, algorithm);
|
||||
private static int TOTP(byte[] key, int period, long time, HashAlgorithm algorithm, int offset) {
|
||||
return HOTP(key, (time / period) + offset, algorithm);
|
||||
}
|
||||
|
||||
private static int HOTP(byte[] key, long counter, HashAlgorithm algorithm)
|
||||
|
@ -119,9 +124,9 @@ public class TokenCalculator {
|
|||
return r;
|
||||
}
|
||||
|
||||
public static String MOTP(String PIN, String secret, long epoch)
|
||||
public static String MOTP(String PIN, String secret, long epoch, int offset)
|
||||
{
|
||||
String epochText = String.valueOf(epoch / 10);
|
||||
String epochText = String.valueOf((epoch / 10) + offset);
|
||||
String hashText = epochText + secret + PIN;
|
||||
String otp = "";
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
private final LinearLayout coverLayout;
|
||||
private final LinearLayout counterLayout;
|
||||
private final FrameLayout thumbnailFrame;
|
||||
private final ImageView visibleImg;
|
||||
private final ImageView thumbnailImg;
|
||||
private final ImageButton menuButton;
|
||||
private final ImageButton copyButton;
|
||||
private final TextView value;
|
||||
private final TextView valuePrev;
|
||||
private final TextView label;
|
||||
private final TextView counter;
|
||||
private final TextView tags;
|
||||
|
@ -86,8 +86,8 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
|
||||
card = v.findViewById(R.id.card_view);
|
||||
value = v.findViewById(R.id.valueText);
|
||||
valuePrev = v.findViewById(R.id.valueTextPrev);
|
||||
valueLayout = v.findViewById(R.id.valueLayout);
|
||||
visibleImg = v.findViewById(R.id.valueImg);
|
||||
thumbnailFrame = v.findViewById(R.id.thumbnailFrame);
|
||||
thumbnailImg = v.findViewById(R.id.thumbnailImg);
|
||||
coverLayout = v.findViewById(R.id.coverLayout);
|
||||
|
@ -106,7 +106,6 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
|
||||
menuButton.getDrawable().setColorFilter(colorFilter);
|
||||
copyButton.getDrawable().setColorFilter(colorFilter);
|
||||
visibleImg.getDrawable().setColorFilter(colorFilter);
|
||||
invisibleImg.getDrawable().setColorFilter(colorFilter);
|
||||
|
||||
setupOnClickListeners(menuButton, copyButton);
|
||||
|
@ -221,6 +220,21 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
// save the unformatted token to the tag of this TextView for copy/paste
|
||||
value.setTag(entry.getCurrentOTP());
|
||||
|
||||
if (settings.getShowPrevToken()) {
|
||||
String tokenPrev = entry.getPrevOTP();
|
||||
|
||||
if (tokenPrev != null && !tokenPrev.isEmpty()) {
|
||||
String tokenFormattedPrev = Tools.formatToken(tokenPrev, settings.getTokenSplitGroupSize());
|
||||
|
||||
valuePrev.setVisibility(View.VISIBLE);
|
||||
valuePrev.setText(tokenFormattedPrev);
|
||||
} else {
|
||||
valuePrev.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
valuePrev.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
List<String> entryTags = entry.getTags();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
@ -255,11 +269,9 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
if (entry.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,11 +328,9 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
if (enabled) {
|
||||
valueLayout.setVisibility(View.GONE);
|
||||
coverLayout.setVisibility(View.VISIBLE);
|
||||
visibleImg.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
valueLayout.setVisibility(View.VISIBLE);
|
||||
coverLayout.setVisibility(View.GONE);
|
||||
visibleImg.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,5 +379,6 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
}
|
||||
|
||||
value.setTextColor(textColor);
|
||||
valuePrev.setTextColor(textColor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_margin_xxsmall"
|
||||
android:layout_marginBottom="@dimen/activity_margin_xxsmall"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:contentPadding="0dp"
|
||||
style="?attr/cardStyle">
|
||||
|
@ -21,7 +22,8 @@
|
|||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false">
|
||||
android:baselineAligned="false"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/thumbnailFrame"
|
||||
|
@ -36,7 +38,8 @@
|
|||
android:layout_width="@dimen/card_thumbnail_size"
|
||||
android:layout_height="@dimen/card_thumbnail_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
@ -72,28 +75,31 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/valueImg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
app:srcCompat="@drawable/ic_visibility_visible"/>
|
||||
|
||||
<TextView
|
||||
android:textDirection="ltr"
|
||||
android:id="@+id/valueText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textDirection="ltr"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/valueTextPrev"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textDirection="ltr"
|
||||
android:layout_marginStart="@dimen/activity_margin_small"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/coverLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/coverImg"
|
||||
|
@ -101,6 +107,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
android:alpha="0.4"
|
||||
android:contentDescription="@string/label_hidden"
|
||||
app:srcCompat="@drawable/ic_visibility_invisible"/>
|
||||
|
||||
<TextView
|
||||
|
@ -122,7 +129,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:text="Label"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="18sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewTags"
|
||||
|
@ -131,7 +139,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:text="Tags"
|
||||
android:textSize="13.5sp" />
|
||||
android:textSize="13.5sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -146,12 +155,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:visibility="gone"
|
||||
android:orientation="horizontal" >
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_alarm_gray" />
|
||||
app:srcCompat="@drawable/ic_alarm_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/customPeriod"
|
||||
|
@ -190,6 +201,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:padding="@dimen/activity_margin_small"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/button_card_copy"
|
||||
app:srcCompat="@drawable/ic_content_copy_gray" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -199,6 +211,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:padding="@dimen/activity_margin_small"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/button_card_options"
|
||||
app:srcCompat="@drawable/ic_more_vert_gray" />
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_margin_xsmall"
|
||||
android:layout_marginBottom="@dimen/activity_margin_xsmall"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:contentPadding="0dp"
|
||||
style="?attr/cardStyle">
|
||||
style="?attr/cardStyle" >
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
|
@ -21,7 +23,8 @@
|
|||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false">
|
||||
android:baselineAligned="false"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/thumbnailFrame"
|
||||
|
@ -36,7 +39,8 @@
|
|||
android:layout_width="@dimen/card_thumbnail_size"
|
||||
android:layout_height="@dimen/card_thumbnail_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
@ -72,28 +76,33 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/valueImg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
app:srcCompat="@drawable/ic_visibility_visible"/>
|
||||
|
||||
<TextView
|
||||
android:textDirection="ltr"
|
||||
android:id="@+id/valueText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
android:textStyle="bold"
|
||||
android:textDirection="ltr"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/valueTextPrev"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textDirection="ltr"
|
||||
android:layout_marginStart="@dimen/activity_margin_small"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/coverLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/coverImg"
|
||||
|
@ -101,7 +110,8 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
android:alpha="0.4"
|
||||
app:srcCompat="@drawable/ic_visibility_invisible"/>
|
||||
android:contentDescription="@string/label_hidden"
|
||||
app:srcCompat="@drawable/ic_visibility_invisible" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -122,7 +132,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:text="Label"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="18sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewTags"
|
||||
|
@ -131,7 +142,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:text="Tags"
|
||||
android:textSize="13.5sp" />
|
||||
android:textSize="13.5sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -146,12 +158,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:visibility="gone"
|
||||
android:orientation="horizontal" >
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_alarm_gray" />
|
||||
app:srcCompat="@drawable/ic_alarm_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/customPeriod"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -9,6 +9,7 @@
|
|||
android:layout_marginBottom="@dimen/activity_margin_xsmall"
|
||||
app:contentPadding="0dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
style="?attr/cardStyle">
|
||||
|
||||
|
@ -21,7 +22,8 @@
|
|||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false">
|
||||
android:baselineAligned="false"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/thumbnailFrame"
|
||||
|
@ -29,14 +31,16 @@
|
|||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:paddingStart="@dimen/card_padding_without_corners"
|
||||
android:background="?attr/thumbnailBackground">
|
||||
android:background="?attr/thumbnailBackground"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnailImg"
|
||||
android:layout_width="@dimen/card_thumbnail_size"
|
||||
android:layout_height="@dimen/card_thumbnail_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
@ -69,13 +73,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/valueImg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
app:srcCompat="@drawable/ic_visibility_visible"/>
|
||||
|
||||
<TextView
|
||||
android:textDirection="ltr"
|
||||
android:id="@+id/valueText"
|
||||
|
@ -85,12 +82,22 @@
|
|||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/valueTextPrev"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/activity_margin_small"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textDirection="ltr"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/coverLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/coverImg"
|
||||
|
@ -98,6 +105,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/activity_margin_small"
|
||||
android:alpha="0.4"
|
||||
android:contentDescription="@string/label_hidden"
|
||||
app:srcCompat="@drawable/ic_visibility_invisible"/>
|
||||
|
||||
<TextView
|
||||
|
@ -119,7 +127,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="18sp"
|
||||
android:text="Label"/>
|
||||
android:text="Label"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewTags"
|
||||
|
@ -128,7 +137,8 @@
|
|||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="13.5sp"
|
||||
android:text="Tags"/>
|
||||
android:text="Tags"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -143,12 +153,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:visibility="gone"
|
||||
android:orientation="horizontal" >
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_alarm_gray" />
|
||||
app:srcCompat="@drawable/ic_alarm_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/customPeriod"
|
||||
|
@ -187,6 +199,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:padding="@dimen/activity_margin_small"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/button_card_copy"
|
||||
app:srcCompat="@drawable/ic_content_copy_gray" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -196,6 +209,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:padding="@dimen/activity_margin_small"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/button_card_options"
|
||||
app:srcCompat="@drawable/ic_more_vert_gray" />
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<string name="settings_key_theme_mode" translatable="false">perf_theme_mode</string>
|
||||
<string name="settings_key_theme_black_auto" translatable="false">pref_theme_black_auto</string>
|
||||
<string name="settings_key_theme" translatable="false">pref_theme</string>
|
||||
<string name="settings_key_show_prev_token" translatable="false">pref_show_prev_token</string>
|
||||
<string name="settings_key_label_size" translatable="false">pref_label_size_sp</string>
|
||||
<string name="settings_key_card_layout" translatable="false">pref_card_layout</string>
|
||||
<string name="settings_key_label_scroll" translatable="false">pref_label_scroll</string> <!-- Deprecated -->
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="MissingTranslation">
|
||||
|
||||
<string name="settings_activity_title">Settings</string>
|
||||
|
||||
<!-- Categories -->
|
||||
|
@ -28,6 +31,7 @@
|
|||
<string name="settings_title_theme_black_auto">Black theme</string>
|
||||
<string name="settings_title_theme">Theme</string>
|
||||
<string name="settings_title_card_layout">Card layout</string>
|
||||
<string name="settings_title_show_prev_token">Show previous token</string>
|
||||
<string name="settings_title_label_size">Label font size</string>
|
||||
<string name="settings_title_label_display">Label display</string>
|
||||
<string name="settings_title_tap_single">Single-tap</string>
|
||||
|
@ -84,6 +88,7 @@
|
|||
above 8.0 (Oreo)</string>
|
||||
|
||||
<string name="settings_desc_theme_black_auto">Use the black theme in dark mode</string>
|
||||
<string name="settings_desc_show_prev_token">Show the previous token in addition to the current one</string>
|
||||
<string name="settings_desc_minimize_on_copy">App will be minimized when you copy the OTP to clipboard</string>
|
||||
<string name="settings_desc_search_includes">Specify which values should be included when searching</string>
|
||||
<string name="settings_desc_label_highlight_token">Highlights token in red if it\'s expiring in 8 seconds</string>
|
||||
|
|
|
@ -143,6 +143,12 @@
|
|||
android:entryValues="@array/settings_values_tap"
|
||||
android:defaultValue="@string/settings_default_tap_double" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="@string/settings_key_show_prev_token"
|
||||
android:title="@string/settings_title_show_prev_token"
|
||||
android:summary="@string/settings_desc_show_prev_token"
|
||||
android:defaultValue="false" />
|
||||
|
||||
<org.shadowice.flocke.andotp.Preferences.NumberPickerPreference
|
||||
android:key="@string/settings_key_label_size"
|
||||
android:title="@string/settings_title_label_size"
|
||||
|
|
Loading…
Reference in a new issue