diff --git a/src/components/Dashboard/index.jsx b/src/components/Dashboard/index.jsx index 1bd585ef..2efd0e03 100644 --- a/src/components/Dashboard/index.jsx +++ b/src/components/Dashboard/index.jsx @@ -1,4 +1,4 @@ -import React, { lazy, Suspense } from 'react'; +import React, { lazy, Suspense, useEffect } from 'react'; import { connect } from 'react-redux'; import Obstruction from 'obstruction'; @@ -18,7 +18,29 @@ const DashboardLoading = () => ( ); +// Persist the dashboard's scroll position across navigation so closing a route +// returns the user to where they were. Stored in sessionStorage keyed by +// dongleId so different devices don't stomp each other. +const useDashboardScrollRestore = (dongleId) => { + useEffect(() => { + if (!dongleId) return undefined; + const key = `dashboard-scroll-${dongleId}`; + + const saved = sessionStorage.getItem(key); + if (saved !== null) { + // Defer to next frame so children have a chance to lay out before we scroll. + requestAnimationFrame(() => window.scrollTo(0, parseInt(saved, 10))); + } + + const onScroll = () => sessionStorage.setItem(key, String(window.scrollY)); + window.addEventListener('scroll', onScroll, { passive: true }); + return () => window.removeEventListener('scroll', onScroll); + }, [dongleId]); +}; + const Dashboard = ({ primeNav, device, dongleId }) => { + useDashboardScrollRestore(primeNav ? null : dongleId); + if (!device || !dongleId) { return ; } diff --git a/src/components/utils/PullDownReload.jsx b/src/components/utils/PullDownReload.jsx index 51015daf..7579a616 100644 --- a/src/components/utils/PullDownReload.jsx +++ b/src/components/utils/PullDownReload.jsx @@ -60,6 +60,14 @@ class PullDownReload extends Component { return; } + // Don't capture touches that start near the screen edges — those are + // iOS' system back-swipe gestures and we shouldn't preventDefault on them. + const x = ev.touches[0].pageX; + const edgeWidth = 30; + if (x < edgeWidth || x > window.innerWidth - edgeWidth) { + return; + } + this.setState({ startY: ev.touches[0].pageY }); }