Add configurable tap action behaviour#1786
Add configurable tap action behaviour#1786michaelschattgen wants to merge 1 commit intobeemdevelopment:masterfrom
Conversation
610b2ab to
99f613b
Compare
alexbakker
left a comment
There was a problem hiding this comment.
I haven't taken a close look at the code yet, but I noticed some issues while doing some initial testing:
- Deselecting the final selected entry no longer closes the action menu
- Entries can no longer be unhighlighted/unrevealed manually
- Navigation to the tap actions preferences submenu is not animated
- Double tapping a hidden entry to copy it, reveals it.
- Settings: Tap to reveal = true, Highlight when tapped = false, Single tap = none, Double tap = Copy, Reserve first tap for reveal = false
- There appears to be a delay for single tap actions
- "Reserve first tap for reveal" also applies to highlighting an entry, but only if you first enable tap to reveal, enable "reserve first tap" and then disable tap to reveal again.
| @@ -200,7 +225,6 @@ | |||
| if (_searchFilter != null) { | |||
| String[] tokens = _searchFilter.toLowerCase().split("\\s+"); | |||
|
|
|||
| // Return true if not all tokens match at least one of the relevant fields | |||
| return !Arrays.stream(tokens) | |||
| .allMatch(token -> | |||
| ((_searchBehaviorMask & Preferences.SEARCH_IN_ISSUER) != 0 && issuer.contains(token)) || | |||
| @@ -287,9 +311,6 @@ | |||
| _entryList = newEntryList; | |||
| updatePeriodUniformity(); | |||
|
|
|||
| // This scroll position trick is required in order to not have the recycler view | |||
| // jump to some random position after a large change (like resorting entries) | |||
| // Related: https://issuetracker.google.com/issues/70149059 | |||
| int scrollPos = _view.getScrollPosition(); | |||
| diffRes.dispatchUpdatesTo(this); | |||
| _view.scrollToPosition(scrollPos); | |||
| @@ -353,8 +374,6 @@ | |||
|
|
|||
| @Override | |||
| public void onItemDrop(int position) { | |||
| // moving entries is not allowed when a filter is applied | |||
| // footer cant be moved, nor can items be moved below it | |||
| if (!_groupFilter.isEmpty() || _entryList.isPositionFooter(position) || _entryList.isPositionErrorCard(position)) { | |||
| return; | |||
| } | |||
| @@ -365,22 +384,18 @@ | |||
|
|
|||
| @Override | |||
| public void onItemMove(int firstPosition, int secondPosition) { | |||
| // Moving entries is not allowed when a filter is applied. The footer can't be | |||
| // moved, nor can items be moved below it | |||
| if (!_groupFilter.isEmpty() | |||
| || _entryList.isPositionFooter(firstPosition) || _entryList.isPositionFooter(secondPosition) | |||
| || _entryList.isPositionErrorCard(firstPosition) || _entryList.isPositionErrorCard(secondPosition)) { | |||
| return; | |||
| } | |||
|
|
|||
| // Notify the vault about the entry position change first | |||
| int firstIndex = _entryList.translateEntryPosToIndex(firstPosition); | |||
| int secondIndex = _entryList.translateEntryPosToIndex(secondPosition); | |||
| VaultEntry firstEntry = _entryList.getShownEntries().get(firstIndex); | |||
| VaultEntry secondEntry = _entryList.getShownEntries().get(secondIndex); | |||
| _view.onEntryMove(firstEntry, secondEntry); | |||
|
|
|||
| // Then update the visual end | |||
| List<VaultEntry> newEntries = new ArrayList<>(_entryList.getEntries()); | |||
| CollectionUtils.move(newEntries, newEntries.indexOf(firstEntry), newEntries.indexOf(secondEntry)); | |||
| replaceEntryList(new EntryList( | |||
| @@ -446,7 +461,6 @@ | |||
| boolean showProgress = entry.getInfo() instanceof TotpInfo && ((TotpInfo) entry.getInfo()).getPeriod() != getMostFrequentPeriod(); | |||
| boolean showAccountName = true; | |||
| if (_onlyShowNecessaryAccountNames) { | |||
| // Only show account name when there's multiple entries found with the same issuer. | |||
| showAccountName = _entryList.getEntries().stream() | |||
| .filter(x -> x.getIssuer().equals(entry.getIssuer())) | |||
| .count() > 1; | |||
| @@ -464,43 +478,9 @@ | |||
| entryHolder.itemView.setOnClickListener(new View.OnClickListener() { | |||
There was a problem hiding this comment.
Why were these comments removed?
There was a problem hiding this comment.
Why were these comments removed?
| @@ -396,7 +398,7 @@ | |||
| <string name="pref_groups_multiselect_summary">Allow the selection of multiple groups at the same time</string> | |||
| <string name="pref_minimize_on_copy_title">Minimize on copy</string> | |||
| <string name="pref_minimize_on_copy_summary">Minimize the app after copying a token</string> | |||
| <string name="pref_copy_behavior_title">Copy tokens to the clipboard</string> | |||
| <string name="pref_copy_behavior_title" tools:ignore="UnusedResources">Copy tokens to the clipboard</string> | |||
| <string name="pref_search_behavior_title">Search behavior</string> | |||
| <string name="pref_pause_entry_title">Freeze tokens when tapped</string> | |||
| <string name="pref_pause_entry_summary">Pause automatic refresh of tokens by tapping them. Tokens will not update as long as they are focused. Requires \"Highlight tokens when tapped\" or \"Tap to reveal\".</string> | |||
| @@ -539,10 +541,6 @@ | |||
| <string name="dialog_wipe_entries_message">Your vault already contains entries. Do you want to remove these entries before importing this file?\n\n<b>In doing so, you will permanently lose access to the existing entries in the vault.</b></string> | |||
| <string name="dialog_wipe_entries_checkbox">Wipe vault contents</string> | |||
|
|
|||
| <string name="import_from_clipboard_title">Import from clipboard</string> | |||
|
|
|||
| <string name="import_from_clipboard_message">We found a valid otpauth uri on your clipboard.\n\n<b>Name</b>: %1$s\n<b>Issuer</b>: %2$s\n\nDo you want to use it to prefill this entry?</string> | |||
|
|
|||
| <string name="panic_trigger_ignore_toast">Aegis received panic trigger but setting is disabled, ignoring</string> | |||
| <string name="pref_panic_trigger_title">Delete vault on panic trigger</string> | |||
| <string name="pref_panic_trigger_summary">Delete vault when a panic trigger is received from Ripple</string> | |||
| @@ -590,9 +588,9 @@ | |||
| <string name="pref_grouping_size_three">Groups of 3</string> | |||
| <string name="pref_grouping_size_four">Groups of 4</string> | |||
|
|
|||
| <string name="pref_copy_behavior_never">Never</string> | |||
| <string name="pref_copy_behavior_single_tap">Single tap</string> | |||
| <string name="pref_copy_behavior_double_tap">Double tap</string> | |||
| <string name="pref_copy_behavior_never" tools:ignore="UnusedResources">Never</string> | |||
| <string name="pref_copy_behavior_single_tap" tools:ignore="UnusedResources">Single tap</string> | |||
| <string name="pref_copy_behavior_double_tap" tools:ignore="UnusedResources">Double tap</string> | |||
|
|
|||
There was a problem hiding this comment.
Let's remove strings that are no longer used.
| <Preference | ||
| android:key="pref_tap_actions_hint" | ||
| android:title="@string/pref_tap_actions_hint_title" | ||
| android:summary="@string/pref_tap_actions_hint_summary" | ||
| android:selectable="false" | ||
| app:iconSpaceReserved="false" /> |
There was a problem hiding this comment.
I think this looks a little bit too much like an actual preference you can tap. I'd suggest making this look the same as the D2D hint we have at the bottom of the Backups preference screen.
| public int getItemCount() { | ||
| // Always at least one item because of the footer | ||
| // Two in case there's also an error card | ||
| int baseCount = 1; | ||
| if (isErrorCardShown()) { | ||
| baseCount++; | ||
| } | ||
|
|
||
| return baseCount + getShownEntries().size(); | ||
| } | ||
|
|
||
| @Nullable | ||
| public ErrorCardInfo getErrorCardInfo() { | ||
| return _errorCardInfo; | ||
| } | ||
|
|
||
| public boolean isErrorCardShown() { | ||
| return _errorCardInfo != null; | ||
| } | ||
|
|
||
| public boolean isPositionErrorCard(int position) { | ||
| return isErrorCardShown() && position == 0; | ||
| } | ||
|
|
||
| public boolean isPositionFooter(int position) { | ||
| return position == (getItemCount() - 1); | ||
| } | ||
|
|
||
| /** | ||
| * Translates the given entry position in the recycler view, to its index in the shown entries list. | ||
| */ | ||
| public int translateEntryPosToIndex(int position) { | ||
| if (position == NO_POSITION) { | ||
| return NO_POSITION; | ||
| } | ||
|
|
||
| if (isErrorCardShown()) { | ||
| position -= 1; | ||
| } | ||
|
|
||
| return position; | ||
| } | ||
|
|
||
| /** | ||
| * Translates the given entry index in the shown entries list, to its position in the recycler view. | ||
| */ | ||
| public int translateEntryIndexToPos(int index) { |
There was a problem hiding this comment.
Why were these comments removed?
| <?xml version="1.0" encoding="utf-8"?> | ||
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||
| xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| android:title="@string/pref_tap_actions_title"> |
There was a problem hiding this comment.
This title does not appear to get applied.
This PR adds the ability to set the single tap and double tap behaviour respectively. This allows us to branch out to other tap actions like the one mentioned in (but not exclusive to) #1688.
Hopefully this PR fixes issues like the ones described in #1223, #1569, #1064, #1667 and probably many more that I can't find right now.
I also added a preferences migration for people who already have set up their 'Copy to clipboard' to either single tap or double tap.