mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-19 21:39:18 +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;
|
||||
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -17,6 +22,7 @@ import com.beemdevelopment.aegis.Preferences;
|
|||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
||||
import com.beemdevelopment.aegis.helpers.CenterVerticalSpan;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
|
||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||
|
@ -276,6 +282,10 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
}
|
||||
|
||||
private void updateCode() {
|
||||
_profileCode.setText(getOtp());
|
||||
}
|
||||
|
||||
private String getOtp() {
|
||||
OtpInfo info = _entry.getInfo();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
_profileCode.setText(otp);
|
||||
return otp;
|
||||
}
|
||||
|
||||
private String formatCode(String code) {
|
||||
|
@ -330,12 +340,53 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
}
|
||||
|
||||
public void hideCode() {
|
||||
String hiddenText = new String(new char[_entry.getInfo().getDigits()]).replace("\0", Character.toString(HIDDEN_CHAR));
|
||||
hiddenText = formatCode(hiddenText);
|
||||
_profileCode.setText(hiddenText);
|
||||
String code = getOtp();
|
||||
String hiddenText = code.replaceAll("\\S", Character.toString(HIDDEN_CHAR));
|
||||
updateTextViewWithDots(_profileCode, hiddenText, code);
|
||||
|
||||
_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) {
|
||||
if (show) {
|
||||
_profileDrawable.setVisibility(View.VISIBLE);
|
||||
|
|
Loading…
Add table
Reference in a new issue