Change hide code behavior, Add HOTP refresh button

This commit is contained in:
MrLetsplay 2023-09-28 21:55:04 +02:00
parent c737dd903b
commit 59bbdc26a7
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
4 changed files with 61 additions and 16 deletions

View File

@ -154,7 +154,7 @@ public class SettingsFragment extends NamedFragment {
requireActivity().recreate(); requireActivity().recreate();
}); });
binding.settingsHideCodes.setChecked(SettingsUtil.isHideCodes(requireContext())); // TODO: implement functionality binding.settingsHideCodes.setChecked(SettingsUtil.isHideCodes(requireContext()));
binding.settingsHideCodes.setOnCheckedChangeListener((view, checked) -> SettingsUtil.setHideCodes(requireContext(), checked)); binding.settingsHideCodes.setOnCheckedChangeListener((view, checked) -> SettingsUtil.setHideCodes(requireContext(), checked));
String[] themeNames = new String[Theme.values().length]; String[] themeNames = new String[Theme.values().length];
@ -300,7 +300,6 @@ public class SettingsFragment extends NamedFragment {
private void loadBackup(Uri uri, SecretKey key, CryptoParameters parameters) throws BackupException, OTPDatabaseException, CryptoException { private void loadBackup(Uri uri, SecretKey key, CryptoParameters parameters) throws BackupException, OTPDatabaseException, CryptoException {
BackupData data = BackupUtil.loadBackup(requireContext(), uri); BackupData data = BackupUtil.loadBackup(requireContext(), uri);
OTPDatabase db = data.loadDatabase(key, parameters); OTPDatabase db = data.loadDatabase(key, parameters);
// TODO: prompt user that all current data will be deleted
OTPDatabase.promptLoadDatabase(requireActivity(), () -> { OTPDatabase.promptLoadDatabase(requireActivity(), () -> {
OTPDatabase oldDatabase = OTPDatabase.getLoadedDatabase(); OTPDatabase oldDatabase = OTPDatabase.getLoadedDatabase();
try { try {

View File

@ -72,23 +72,32 @@ public class OTPListAdapter extends RecyclerView.Adapter<OTPListItem> {
} }
holder.getBinding().label.setText(String.format("%s%s", data.getIssuer() == null || data.getIssuer().isEmpty() ? "" : data.getIssuer() + ": ", data.getName())); holder.getBinding().label.setText(String.format("%s%s", data.getIssuer() == null || data.getIssuer().isEmpty() ? "" : data.getIssuer() + ": ", data.getName()));
holder.getBinding().progress.setVisibility(data.getType() == OTPType.TOTP ? View.VISIBLE : View.INVISIBLE); holder.getBinding().progress.setVisibility(data.getType() == OTPType.TOTP ? View.VISIBLE : View.GONE);
holder.getBinding().refresh.setVisibility(data.getType() == OTPType.HOTP ? View.VISIBLE : View.GONE);
holder.getBinding().refresh.setOnClickListener(view -> {
if (data.getType() != OTPType.HOTP) return;
if(!holder.isCodeShown()) {
showCode(holder);
}
// Click delay for HOTP
view.setEnabled(false);
data.incrementCounter();
saveOTPs.run();
Toast.makeText(view.getContext(), R.string.hotp_generated_new_code, Toast.LENGTH_SHORT).show();
handler.postDelayed(() -> view.setEnabled(true), 5000);
});
holder.getBinding().getRoot().setOnClickListener(view -> { holder.getBinding().getRoot().setOnClickListener(view -> {
if(!editing) { if(!editing) {
if (!view.isClickable()) return; if(!holder.isCodeShown()) {
showCode(holder);
if(!holder.isCodeShown()) holder.setCodeShown(true); }else {
holder.setCodeShown(false);
if (data.getType() == OTPType.HOTP) {
// Click delay for HOTP
view.setClickable(false);
data.incrementCounter();
saveOTPs.run();
Toast.makeText(view.getContext(), R.string.hotp_generated_new_code, Toast.LENGTH_SHORT).show();
handler.postDelayed(() -> view.setClickable(true), 5000);
} }
try { try {
@ -168,6 +177,31 @@ public class OTPListAdapter extends RecyclerView.Adapter<OTPListItem> {
return selected; return selected;
} }
private void showCode(OTPListItem item) {
for(OTPListItem h : getCodes()) {
if(h.isCodeShown()) {
h.setCodeShown(false);
try {
h.refresh();
} catch (OTPException e) {
DialogUtil.showErrorDialog(context, e.getMessage() == null ? "An error occurred while refreshing the code" : e.getMessage());
}
}
}
item.setCodeShown(true);
}
private List<OTPListItem> getCodes() {
List<OTPListItem> is = new ArrayList<>();
for(int i = 0; i < items.size(); i++) {
OTPListItem vh = (OTPListItem) recyclerView.findViewHolderForAdapterPosition(i);
if(vh == null) continue;
is.add(vh);
}
return is;
}
private void attachTouchHelper(RecyclerView view) { private void attachTouchHelper(RecyclerView view) {
new ItemTouchHelper(new OTPListAdapter.TouchHelperCallback()).attachToRecyclerView(view); new ItemTouchHelper(new OTPListAdapter.TouchHelperCallback()).attachToRecyclerView(view);
} }

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="?android:attr/textColor"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>

View File

@ -70,6 +70,13 @@
android:layout_height="30dp" android:layout_height="30dp"
app:srcCompat="@drawable/progress_circle" /> app:srcCompat="@drawable/progress_circle" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/refresh"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@null"
app:srcCompat="@drawable/baseline_refresh_24" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>