mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-19 13:29:13 +00:00
Merge pull request #1458 from michaelschattgen/fix/hidden-dots-size
Fix sizing inconsistency of the dots in hidden view
This commit is contained in:
commit
9eae773efb
2 changed files with 85 additions and 4 deletions
|
@ -0,0 +1,30 @@
|
||||||
|
package com.beemdevelopment.aegis.helpers;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.text.style.MetricAffectingSpan;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
public class CenterVerticalSpan extends MetricAffectingSpan {
|
||||||
|
Rect _substringBounds;
|
||||||
|
|
||||||
|
public CenterVerticalSpan(Rect substringBounds) {
|
||||||
|
_substringBounds = substringBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMeasureState(@NonNull TextPaint textPaint) {
|
||||||
|
applyBaselineShift(textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDrawState(@NonNull TextPaint textPaint) {
|
||||||
|
applyBaselineShift(textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyBaselineShift(TextPaint textPaint) {
|
||||||
|
float topDifference = textPaint.getFontMetrics().top - _substringBounds.top;
|
||||||
|
textPaint.baselineShift -= (topDifference / 2f);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
package com.beemdevelopment.aegis.ui.views;
|
package com.beemdevelopment.aegis.ui.views;
|
||||||
|
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.style.RelativeSizeSpan;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -17,6 +22,7 @@ import com.beemdevelopment.aegis.Preferences;
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.ViewMode;
|
import com.beemdevelopment.aegis.ViewMode;
|
||||||
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
||||||
|
import com.beemdevelopment.aegis.helpers.CenterVerticalSpan;
|
||||||
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
|
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
|
||||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||||
|
@ -276,6 +282,10 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCode() {
|
private void updateCode() {
|
||||||
|
_profileCode.setText(getOtp());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOtp() {
|
||||||
OtpInfo info = _entry.getInfo();
|
OtpInfo info = _entry.getInfo();
|
||||||
|
|
||||||
// In previous versions of Aegis, it was possible to import entries with an empty
|
// In previous versions of Aegis, it was possible to import entries with an empty
|
||||||
|
@ -292,7 +302,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
otp = _view.getResources().getString(R.string.error_all_caps);
|
otp = _view.getResources().getString(R.string.error_all_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
_profileCode.setText(otp);
|
return otp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatCode(String code) {
|
private String formatCode(String code) {
|
||||||
|
@ -330,12 +340,53 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideCode() {
|
public void hideCode() {
|
||||||
String hiddenText = new String(new char[_entry.getInfo().getDigits()]).replace("\0", Character.toString(HIDDEN_CHAR));
|
String code = getOtp();
|
||||||
hiddenText = formatCode(hiddenText);
|
String hiddenText = code.replaceAll("\\S", Character.toString(HIDDEN_CHAR));
|
||||||
_profileCode.setText(hiddenText);
|
updateTextViewWithDots(_profileCode, hiddenText, code);
|
||||||
|
|
||||||
_hidden = true;
|
_hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateTextViewWithDots(TextView textView, String hiddenCode, String code) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setTextSize(_profileCode.getTextSize());
|
||||||
|
|
||||||
|
// Calculate the difference between the actual code width and the dots width
|
||||||
|
float codeWidth = paint.measureText(code);
|
||||||
|
float dotsWidth = paint.measureText(hiddenCode);
|
||||||
|
float scaleFactor = codeWidth / dotsWidth;
|
||||||
|
scaleFactor = (float)(Math.round(scaleFactor * 10.0) / 10.0);
|
||||||
|
|
||||||
|
// If scale is higher or equal to 0.8, do nothing and proceed with the normal text rendering
|
||||||
|
if (scaleFactor >= 0.8) {
|
||||||
|
textView.setText(hiddenCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to use an invisible character in order to get the height of the profileCode textview consistent
|
||||||
|
// Tokens without a space (ie Steam TOTP) will get misaligned without this
|
||||||
|
SpannableString dotsString = new SpannableString("\u200B" + hiddenCode);
|
||||||
|
|
||||||
|
// Only scale the digits/characters, skip the spaces
|
||||||
|
int start = 1;
|
||||||
|
for (int i = 0; i <= dotsString.length(); i++) {
|
||||||
|
if (i == dotsString.length() || dotsString.charAt(i) == ' ') {
|
||||||
|
if (i > start) {
|
||||||
|
dotsString.setSpan(new RelativeSizeSpan(scaleFactor), start, i, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect dotsRectBounds = new Rect();
|
||||||
|
paint.getTextBounds(hiddenCode, 1, hiddenCode.length(), dotsRectBounds);
|
||||||
|
|
||||||
|
// Use custom CenterVerticalSpan to make sure the dots are vertically aligned
|
||||||
|
dotsString.setSpan(new CenterVerticalSpan(dotsRectBounds), 1, dotsString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
textView.setText(dotsString);
|
||||||
|
}
|
||||||
|
|
||||||
public void showIcon(boolean show) {
|
public void showIcon(boolean show) {
|
||||||
if (show) {
|
if (show) {
|
||||||
_profileDrawable.setVisibility(View.VISIBLE);
|
_profileDrawable.setVisibility(View.VISIBLE);
|
||||||
|
|
Loading…
Add table
Reference in a new issue