Skip to content

fix(nav): restore the scroll position on Back and Forward - #525

Open
yhabib wants to merge 5 commits into
mainfrom
fix/scroll-restore-on-back
Open

yhabib wants to merge 5 commits into
mainfrom
fix/scroll-restore-on-back

Conversation

@yhabib

@yhabib yhabib commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Motivation

On Android, Back is the main way back, and two things break it. Back to the proposal list always scrolled <main> to the top, so users lost their place (Pixel 9 emulator: the list was at 997px, it came back at 481px). "Back to proposals" pushed a new entry, so the system Back gesture after it returned to the proposal.

Changes

  • Changed useScrollResetOnNavigation to save the <main> scroll position for each history entry and restore it on Back and Forward. A new entry still starts at the top.
  • Kept the saved position while the page content grows for up to 5 s, so a list that loads late still lands at the right place. User input stops it.
  • Skipped the smooth scroll to the proposals section on the voting page when Back or Forward restores the position.
  • Changed "Back to proposals" to go back in history when the proposal list pushed the detail page. Other entries (command palette, deep link) still push /voting.
  • Added tests for the hook.

Back and Forward now restore the scroll position of the page in `<main>`.
The hook saves the position for each history entry. A new entry still starts
at the top. If the list data loads late, the restore waits for it.

"Back to proposals" now goes back in history when the previous entry is the
proposal list. The system Back gesture then does not return to the proposal.
@yhabib
yhabib requested a review from a team as a code owner October 17, 2026 17:51
Copilot AI balanced review requested due to automatic review settings October 17, 2026 17:51
@zeropath-ai

zeropath-ai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

✅ No security or compliance issues detected. Reviewed everything up to 019b0c3.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/governance-app-frontend/src/common/hooks/useScrollResetOnNavigation.ts
    Implement Vercel OAuth Flow
Enhancement ► src/governance-app-frontend/src/routes/_auth/voting/index.tsx
    Use router hook and integrate scroll restoration check
Enhancement ► src/governance-app-frontend/src/routes/_auth/voting/proposals/$id/index.tsx
    Use location state to determine back navigation behavior
Enhancement ► src/governance-app-frontend/src/common/utils/initializer.ts
    Extend HistoryState with fromProposalList flag
Enhancement ► src/governance-app-frontend/src/routes/_auth/voting/index.tsx
    Import and utilize restoresScrollPosition to manage scroll restoration on navigation

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

📊 Build Bundle Stats

The latest build generated the following assets:

dist/index.html                                           5.86 kB │ gzip:   1.65 kB
dist/assets/index-DHR8rj0Y.css                          150.06 kB │ gzip:  24.02 kB
dist/assets/icpLedger-BdFvsufE.js                         0.23 kB │ gzip:   0.21 kB
dist/assets/Skeleton-CaAu4RfS.js                          0.44 kB │ gzip:   0.32 kB
dist/assets/webhid-D0yio6wG.js                            0.53 kB │ gzip:   0.32 kB
dist/assets/useTvlValue-CnQEjDnu.js                       0.60 kB │ gzip:   0.41 kB
dist/assets/nnsDapp-D9Ry-tmL.js                           0.68 kB │ gzip:   0.25 kB
dist/assets/SkeletonPageHeader-CefOWc2a.js                0.76 kB │ gzip:   0.47 kB
dist/assets/PageHeader-jXzaR6sL.js                        0.77 kB │ gzip:   0.45 kB
dist/assets/CertifiedBadge-CZP1zuhA.js                    0.81 kB │ gzip:   0.48 kB
dist/assets/Separator-C6hS-xK5.js                         0.83 kB │ gzip:   0.50 kB
dist/assets/SkeletonStatCard-DhpxB6hR.js                  0.91 kB │ gzip:   0.56 kB
dist/assets/useForecastPeriod-ybwbJ_UQ.js                 1.01 kB │ gzip:   0.61 kB
dist/assets/utils-CeJgzK-h.js                             1.02 kB │ gzip:   0.59 kB
dist/assets/useIcpIndex-uFD-Wj6t.js                       1.09 kB │ gzip:   0.64 kB
dist/assets/numbers-O3mLn7Bo.js                           1.15 kB │ gzip:   0.57 kB
dist/assets/routeLoaders-C8-NazBt.js                      1.19 kB │ gzip:   0.55 kB
dist/assets/rolldown-runtime-DAXXjFlN.js                  1.26 kB │ gzip:   0.70 kB
dist/assets/advancedFeatures-B0jRzw84.js                  1.50 kB │ gzip:   0.74 kB
dist/assets/events-WiKb4_B4.js                            1.66 kB │ gzip:   0.86 kB
dist/assets/SkeletonListRows-DY8ZpiTj.js                  1.69 kB │ gzip:   0.53 kB
dist/assets/useLedgerNeuronCall-BOtBcZlb.js               1.89 kB │ gzip:   1.03 kB
dist/assets/errors-C_oENL0S.js                            1.95 kB │ gzip:   0.97 kB
dist/assets/AnimatedNumber-CfI89_lq.js                    1.98 kB │ gzip:   1.12 kB
dist/assets/useScrollResetOnNavigation-CVNxOTPW.js        2.01 kB │ gzip:   1.06 kB
dist/assets/useCommandPaletteSettings-D9R-n2xL.js         2.13 kB │ gzip:   1.06 kB
dist/assets/addressBook-CmzDRJrC.js                       2.14 kB │ gzip:   1.19 kB
dist/assets/useIcpIndexTransactionsPolling-BGdlTncl.js    2.15 kB │ gzip:   1.15 kB
dist/assets/useGovernanceAppCanister-Bp4Dxg-3.js          2.41 kB │ gzip:   1.07 kB
dist/assets/useShortcutSettings-C3cHA6Oh.js               2.41 kB │ gzip:   1.19 kB
dist/assets/useAddHotkey-Du37mtx5.js                      2.61 kB │ gzip:   1.34 kB
dist/assets/governance-BQavlAiL.js                        2.99 kB │ gzip:   1.15 kB
dist/assets/ToggleGroup-Bozgv4Oc.js                       3.09 kB │ gzip:   1.41 kB
dist/assets/useClaimPendingDeviceStakes-C1JSmnda.js       3.12 kB │ gzip:   1.42 kB
dist/assets/SkeletonText-DoOyIiKX.js                      3.71 kB │ gzip:   1.29 kB
dist/assets/useAccounts-QUuyx9ov.js                       4.96 kB │ gzip:   2.21 kB
dist/assets/tickers-DHej10Ch.js                           6.54 kB │ gzip:   2.73 kB
dist/assets/useNowInSeconds-DQpkEplI.js                   7.12 kB │ gzip:   3.04 kB
dist/assets/DeviceActionDetail-DXaEK0Tc.js                8.45 kB │ gzip:   3.03 kB
dist/assets/TopicFollowingAccordion-BENx8aCt.js           8.55 kB │ gzip:   3.41 kB
dist/assets/routes-C2dIG6pS.js                            8.96 kB │ gzip:   3.07 kB
dist/assets/AlertDialog-aoD_-IYI.js                       8.99 kB │ gzip:   3.16 kB
dist/assets/ledgerIdentity-CbGbEww2.js                   10.16 kB │ gzip:   3.70 kB
dist/assets/MutationDialog-Slt9wGL3.js                   11.55 kB │ gzip:   4.00 kB
dist/assets/spamFilter-Dzlz1VZJ.js                       11.77 kB │ gzip:   5.02 kB
dist/assets/ResponsiveDialog-BC8OMhcL.js                 14.56 kB │ gzip:   4.08 kB
dist/assets/AmountInput-B7MO49-9.js                      16.85 kB │ gzip:   6.73 kB
dist/assets/_id-BnjYAy0n.js                              16.96 kB │ gzip:   5.49 kB
dist/assets/_auth-fx2kD4x8.js                            22.17 kB │ gzip:   8.18 kB
dist/assets/HideBalancesToggle-DRCcC6ge.js               22.99 kB │ gzip:   8.58 kB
dist/assets/vendor-buffer-EX-AqChq.js                    26.95 kB │ gzip:   8.18 kB
dist/assets/accounts-0MPtZ7sB.js                         32.02 kB │ gzip:  10.89 kB
dist/assets/SendICPButton-l8DtOpAL.js                    37.04 kB │ gzip:  13.52 kB
dist/assets/settings-DbEfFSvR.js                         54.42 kB │ gzip:  15.56 kB
dist/assets/dashboard-DsQyJ3Zt.js                        57.80 kB │ gzip:  19.11 kB
dist/assets/index-CWZ1SRfr.js                            62.78 kB │ gzip:  17.84 kB
dist/assets/voting-B9yOi-5V.js                           69.48 kB │ gzip:  21.78 kB
dist/assets/vendor-md-CGr8lPUw.js                        73.29 kB │ gzip:  19.98 kB
dist/assets/button-DjUdSNL2.js                           84.90 kB │ gzip:  28.37 kB
dist/assets/neurons-CX-r0F7P.js                          90.41 kB │ gzip:  27.09 kB
dist/assets/DisburseModal-CIuSQmNZ.js                   101.46 kB │ gzip:  29.62 kB
dist/assets/vendor-tanstack-CfLnVfRK.js                 120.08 kB │ gzip:  39.23 kB
dist/assets/vendor-jsqr-CjiBYtfG.js                     129.98 kB │ gzip:  47.50 kB
dist/assets/vendor-core-react-bRRjyX41.js               189.81 kB │ gzip:  59.76 kB
dist/assets/vendor-recharts-D2GxZz0f.js                 280.26 kB │ gzip:  76.81 kB
dist/assets/vendor-ledger-Bz6feAP8.js                   403.26 kB │ gzip:  98.84 kB
dist/assets/vendor-icp-e5O_ocwA.js                      468.31 kB │ gzip: 117.84 kB
dist/assets/vendor-libs-CXEHHDQp.js                     581.21 kB │ gzip: 186.96 kB

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Input cancellation can leave a stale saved position and cause incorrect scrolling on a later return.

1 open issue
What changed in this PR

Restores navigation scroll positions and makes “Back to proposals” return through history when opened from the list.

Changes:

  • Saves and restores per-entry scroll positions, including delayed content loading.
  • Coordinates proposal navigation with scroll restoration.
  • Adds hook tests for restoration and cancellation.
File Description
src/​governance-app-frontend/​src/​routes/​_auth/​voting/​proposals/​$id/​index.tsx Uses history Back for list-origin navigation.
src/​governance-app-frontend/​src/​routes/​_auth/​voting/​index.tsx Marks list-origin links and skips conflicting scrolling.
src/​governance-app-frontend/​src/​common/​utils/​initializer.ts Types the navigation history marker.
src/​governance-app-frontend/​src/​common/​hooks/​useScrollResetOnNavigation.ts Implements per-entry scroll restoration.
src/​governance-app-frontend/​src/​common/​hooks/​useScrollResetOnNavigation.test.tsx Tests restoration, delayed content, and cancellation.

Review effort: Balanced

Copilot AI previously approved these changes Oct 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approved

Static review identified no unresolved blocking issues; regression tests were inspected but not executed.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 19:24
Copilot AI dismissed their stale review, a newer Copilot review was requested November 5, 2026 19:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Back/Forward navigation between entries with the same pathname overwrites the destination’s saved scroll position instead of restoring it.

1 open issue

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 19:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A pending smooth-scroll timer can overwrite the restored scroll position after Back navigation, so the timeout must recheck restoresScrollPosition before scrolling.

1 open issue
1 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 19:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approved

No active review issues block approval of the navigation and scroll-restoration changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

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.

2 participants