From d1211396764776f58ca39b3b66d8f3bfcbe57b54 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Wed, 28 Oct 2020 15:00:56 +0100 Subject: [PATCH] After adding a new entry, scroll to it and highlight it --- .../aegis/ui/MainActivity.java | 2 +- .../aegis/ui/views/EntryAdapter.java | 37 +++++++++++-------- .../aegis/ui/views/EntryListView.java | 35 +++++++++++++++++- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 647df195..dfa63cef 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -284,7 +284,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene if (_loaded) { UUID entryUUID = (UUID) data.getSerializableExtra("entryUUID"); VaultEntry entry = _vault.getEntryByUUID(entryUUID); - _entryListView.addEntry(entry); + _entryListView.addEntry(entry, true); } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java index 76f10b02..bcbf12af 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java @@ -37,6 +37,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I private boolean _showAccountName; private boolean _searchAccountName; private boolean _highlightEntry; + private boolean _tempHighlightEntry; private boolean _tapToReveal; private int _tapToRevealTime; private boolean _copyOnTap; @@ -92,6 +93,10 @@ public class EntryAdapter extends RecyclerView.Adapter implements I _highlightEntry = highlightEntry; } + public void setTempHighlightEntry(boolean highlightEntry) { + _tempHighlightEntry = highlightEntry; + } + public void setIsCopyOnTapEnabled(boolean enabled) { _copyOnTap = enabled; } @@ -100,13 +105,13 @@ public class EntryAdapter extends RecyclerView.Adapter implements I return _shownEntries.get(position); } - public void addEntry(VaultEntry entry) { + public int addEntry(VaultEntry entry) { _entries.add(entry); if (isEntryFiltered(entry)) { - return; + return -1; } - boolean added = false; + int position = -1; Comparator comparator = _sortCategory.getComparator(); if (comparator != null) { // insert the entry in the correct order @@ -115,16 +120,16 @@ public class EntryAdapter extends RecyclerView.Adapter implements I if (comparator.compare(_shownEntries.get(i), entry) > 0) { _shownEntries.add(i, entry); notifyItemInserted(i); - added = true; + position = i; break; } } } - if (!added){ + if (position < 0){ _shownEntries.add(entry); - int position = getItemCount() - 1; + position = getItemCount() - 1; if (position == 0) { notifyDataSetChanged(); } else { @@ -134,6 +139,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I _view.onListChange(); checkPeriodUniformity(); + return position; } public void addEntries(Collection entries) { @@ -341,7 +347,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I VaultEntry entry = _shownEntries.get(position); boolean hidden = _tapToReveal && entry != _focusedEntry; - boolean dimmed = _highlightEntry && _focusedEntry != null && _focusedEntry != entry; + boolean dimmed = (_highlightEntry || _tempHighlightEntry) && _focusedEntry != null && _focusedEntry != entry; boolean showProgress = entry.getInfo() instanceof TotpInfo && ((TotpInfo) entry.getInfo()).getPeriod() != getMostFrequentPeriod(); holder.setData(entry, _codeGroupSize, _showAccountName, showProgress, hidden, dimmed); holder.setFocused(_selectedEntries.contains(entry)); @@ -358,12 +364,12 @@ public class EntryAdapter extends RecyclerView.Adapter implements I holder.animateCopyText(); } - if (_highlightEntry || _tapToReveal) { + if (_highlightEntry || _tempHighlightEntry || _tapToReveal) { if (_focusedEntry == entry) { resetFocus(); handled = true; } else { - focusEntry(entry); + focusEntry(entry, _tapToRevealTime); } } } else { @@ -497,20 +503,20 @@ public class EntryAdapter extends RecyclerView.Adapter implements I return maxValue > 1 ? maxKey : -1; } - private void focusEntry(VaultEntry entry) { + public void focusEntry(VaultEntry entry, int secondsToFocus) { _focusedEntry = entry; _dimHandler.removeCallbacksAndMessages(null); for (EntryHolder holder : _holders) { if (holder.getEntry() != _focusedEntry) { - if (_highlightEntry) { + if (_highlightEntry || _tempHighlightEntry) { holder.dim(); } if (_tapToReveal) { holder.hideCode(); } } else { - if (_highlightEntry) { + if (_highlightEntry || _tempHighlightEntry) { holder.highlight(); } if (_tapToReveal) { @@ -519,12 +525,12 @@ public class EntryAdapter extends RecyclerView.Adapter implements I } } - _dimHandler.postDelayed(this::resetFocus, _tapToRevealTime * 1000); + _dimHandler.postDelayed(this::resetFocus, secondsToFocus * 1000); } private void resetFocus() { for (EntryHolder holder : _holders) { - if (_highlightEntry) { + if (_focusedEntry != null) { holder.highlight(); } if (_tapToReveal) { @@ -533,6 +539,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I } _focusedEntry = null; + _tempHighlightEntry = false; } private void updateDraggableStatus() { @@ -565,7 +572,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I } public void addSelectedEntry(VaultEntry entry) { - if (_highlightEntry) { + if (_focusedEntry != null) { resetFocus(); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java index 290a498e..3e2079ba 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java @@ -1,9 +1,11 @@ package com.beemdevelopment.aegis.ui.views; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; @@ -273,8 +275,39 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { } public void addEntry(VaultEntry entry) { - _adapter.addEntry(entry); + addEntry(entry, false); + } + + @SuppressLint("ClickableViewAccessibility") + public void addEntry(VaultEntry entry, boolean focusEntry) { + int position = _adapter.addEntry(entry); updateEmptyState(); + + if (focusEntry && position >= 0) { + RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + _recyclerView.removeOnScrollListener(this); + _adapter.setTempHighlightEntry(true); + + final int secondsToFocus = 3; + _adapter.focusEntry(entry, secondsToFocus); + } + } + }; + _recyclerView.addOnScrollListener(scrollListener); + _recyclerView.setOnTouchListener((v, event) -> { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + _recyclerView.removeOnScrollListener(scrollListener); + _recyclerView.stopScroll(); + _recyclerView.setOnTouchListener(null); + } + + return false; + }); + _recyclerView.smoothScrollToPosition(position); + } } public void addEntries(Collection entries) {