Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-13388] Extension: Persist Scroll from Vault #12325

Merged
merged 26 commits into from
Jan 28, 2025

Conversation

nick-livefront
Copy link
Collaborator

@nick-livefront nick-livefront commented Dec 9, 2024

🎟️ Tracking

PM-13388

📔 Objective

Persist the scroll position on the vault screen within the extension.

  • The scroll position of the CdkVirtualScrollableElement is stored within VaultPopupScrollPositionService
    • When the vault screen is initialized the stored value is scrolled into view. This is set behind a setTimeout to ensure that the next render cycle is hit.
    • Navigation events are tracked to determine which cipher was viewed. The service then uses an added data-id attribute to focus on the given cipher that was viewed.
      • Because the items are virtualized this needs the scroll to be complete in order for the item to be in the DOM.
      • ❓ I added a method to track the scroll position on an interval. In my testing another setTimeout would work because the page is "instantly" scrolled but it felt less intentional. I'm open to thoughts though!
      • Logic removed after discussion with Danielle: [PM-13388] Extension: Persist Scroll from Vault #12325 (comment)
  • Scroll Position is reset when:
    • A cipher is deleted
    • A tab page is navigated to other than the vault, i.e. /tabs/generator

📸 Screenshots

Persist Scroll & Focus Reset for Other Pages Reset on Deletion
preserve-scroll.mov
reset-for-other-tabs.mov
delete-reset-scroll.mov

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@nick-livefront nick-livefront requested a review from a team as a code owner December 9, 2024 21:41
Copy link
Contributor

github-actions bot commented Dec 9, 2024

Logo
Checkmarx One – Scan Summary & Details1c8c1b01-7262-4e89-9953-9184e3f461c6

Great job, no security vulnerabilities found in this Pull Request

@nick-livefront nick-livefront marked this pull request as draft December 9, 2024 21:52
@nick-livefront nick-livefront marked this pull request as ready for review December 9, 2024 22:46
Copy link

codecov bot commented Dec 9, 2024

Codecov Report

Attention: Patch coverage is 67.39130% with 15 lines in your changes missing coverage. Please review.

Project coverage is 35.22%. Comparing base (ecb0d1e) to head (22131d1).
Report is 87 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...lt/popup/components/vault-v2/vault-v2.component.ts 0.00% 11 Missing ⚠️
...up/services/vault-popup-scroll-position.service.ts 89.28% 0 Missing and 3 partials ⚠️
...vault-list-filters/vault-list-filters.component.ts 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12325      +/-   ##
==========================================
+ Coverage   35.01%   35.22%   +0.21%     
==========================================
  Files        2973     2993      +20     
  Lines       90457    90716     +259     
  Branches    16955    16974      +19     
==========================================
+ Hits        31670    31959     +289     
+ Misses      56330    56289      -41     
- Partials     2457     2468      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@danielleflinn
Copy link
Member

@nick-livefront this looks great! One nit, it is a bit odd that the focus ring flashes on search and then moves down to the item. It feels like a bug. When navigating with a screen reader on, the UX isn't terrible but I can hear the SR trying to read the first few syllables of "search" before focus is moved on.

Is there a way for us to keep auto-focus on search just when initially opening the popup so we don't have the flash of the search focus in this flow?

@nick-livefront
Copy link
Collaborator Author

Is there a way for us to keep auto-focus on search just when initially opening the popup so we don't have the flash of the search focus in this flow?

@danielleflinn The focus only moves when navigating back from a cipher view screen. Which I agree, not ideal. Initially opening the extension or navigating from another page the focus stays on the search field.

Do you want to remove the focus switch when navigating back from the view page?

Screen.Recording.2024-12-11.at.11.29.06.AM.mov

@danielleflinn
Copy link
Member

@nick-livefront yes, let's go ahead and remove the focus redirect, so after returning to the Vault view in this flow focus will remain on "Search". This matches the behavior of the legacy extension. I'll update the jira to reflect the scope change.

Thanks for the discussion and flexibility!

Jingo88
Jingo88 previously approved these changes Dec 26, 2024
@nick-livefront
Copy link
Collaborator Author

@Jingo88 Re-requesting your review. Brad noticed an odd scroll bug where the list can shift downward as you go in and out of viewing a cipher.

I deduced that down to the scrolling subscription tracking the automatic scroll, I added a skip(1) to remediate.

554fc0c

@nick-livefront nick-livefront requested a review from Jingo88 January 3, 2025 16:58
Jingo88
Jingo88 previously approved these changes Jan 3, 2025
shane-melton
shane-melton previously approved these changes Jan 9, 2025
Copy link
Member

@shane-melton shane-melton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just two non-blocking nits/suggestions

@@ -85,10 +88,18 @@ export class VaultV2Component implements OnInit, OnDestroy {

protected VaultStateEnum = VaultState;

private allFilters$ = combineLatest([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ (non-blocking): We could probably just expose / re-use the allFilters$ we defined on the filter service.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳 50a5b6b

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll raise a separate PR to go back and fix the filter component once this merges in

// Use `setTimeout` to scroll after rendering is complete
setTimeout(async () => {
// `?? 0` is only to make typescript happy. It shouldn't happen with the above truthy check for `this.scrollPosition`.
virtualScrollElement.scrollTo({ top: this.scrollPosition ?? 0, behavior: "instant" });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ (non-blocking): We can also use the non-null assertion operator (!) and avoid the ?? 0 and explanatory comment.

Suggested change
virtualScrollElement.scrollTo({ top: this.scrollPosition ?? 0, behavior: "instant" });
virtualScrollElement.scrollTo({ top: this.scrollPosition!, behavior: "instant" });

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nick-livefront
Copy link
Collaborator Author

@cd-bitwarden @shane-melton Fixed Shane's two nits and conflicts from main, re-requesting your review!

shane-melton
shane-melton previously approved these changes Jan 9, 2025
@nick-livefront
Copy link
Collaborator Author

@bitwarden/team-vault-dev For large vaults there was a "jump" occurring for the user, this starts occurring at around 500+ ciphers.

I tried a couple different options of trying to solve for the jump but the straight forward approach felt the most reasonable. Simply hiding the scroll element until after the scroll takes place.

Jump Hide and Show
jump.mov
hide-n-show.mov

@gbubemismith
Copy link
Member

@bitwarden/team-vault-dev For large vaults there was a "jump" occurring for the user, this starts occurring at around 500+ ciphers.

I tried a couple different options of trying to solve for the jump but the straight forward approach felt the most reasonable. Simply hiding the scroll element until after the scroll takes place.

Jump Hide and Show
jump.mov
hide-n-show.mov

I think this solution is nice. Thanks for pointing that out. I think you should also add a comment for why we did this.

@nick-livefront
Copy link
Collaborator Author

I think this solution is nice. Thanks for pointing that out. I think you should also add a comment for why we did this.

@gbubemismith Yes! I added two comments, one at the implementation and at the source

gbubemismith
gbubemismith previously approved these changes Jan 14, 2025
@@ -130,7 +130,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
ngAfterViewInit(): void {
if (this.virtualScrollElement) {
// Hide the virtual scroll element briefly before the `vaultScrollPositionService` starts.
// This avoids having the scrolling element "jump" visually for the user and
// This avoids having the scrolling element "jump" visually for the user when they have larger vaults.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼

@nick-livefront nick-livefront merged commit 08c42a8 into main Jan 28, 2025
35 of 36 checks passed
@nick-livefront nick-livefront deleted the vault/pm-13888/persist-scroll-from-vault branch January 28, 2025 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants