Skip to content

Instantly share code, notes, and snippets.

@sbdchd
Created July 15, 2022 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbdchd/ff245937806465dcbb52215bd3d04a35 to your computer and use it in GitHub Desktop.
Save sbdchd/ff245937806465dcbb52215bd3d04a35 to your computer and use it in GitHub Desktop.
instagram scroll position stuff
import Polarisunexpected from "Polarisunexpected"
import PolarisIGWebStorage from "PolarisIGWebStorage"
import ExecutionEnvironment from "ExecutionEnvironment"
import browserHistory from "browserHistory"
import PolarisEventListener from "PolarisEventListener"
import PolarisRoutes from "PolarisRoutes"
import qex from "qex"
/** @type {Record<string, string>} */
let scrollHistory = {}
let initialized = false
function initialScrollHistory() {
const storage = PolarisIGWebStorage.getStorageForUser()
if (storage) {
const scrollPos = storage.getItem("routeScrollPos")
try {
scrollHistory =
scrollPos != null && scrollPos !== "" ? JSON.parse(scrollPos) : {}
} catch (err) {
Polarisunexpected(
"Error parsing routeScrollPos from scrollPositionHistory"
)
}
}
}
initialScrollHistory()
export function disableNativeScrollRestoration() {
initialized = true
if (ExecutionEnvironment.canUseDOM && "scrollRestoration" in history) {
history.scrollRestoration = "manual"
}
}
export function clearScrollPosition(location) {
const storage = PolarisIGWebStorage.getStorageForUser()
const pathname = location.pathname
if (!storage || !pathname) {
return
}
delete scrollHistory[pathname]
storage.setItem("routeScrollPos", JSON.stringify(scrollHistory))
}
export function saveScrollPosition(location, element) {
if (
!ExecutionEnvironment.canUseDOM ||
!document.querySelectorAll("#react-root > *")
) {
return
}
const storage = PolarisIGWebStorage.getStorageForUser()
const pathname = location.pathname
if (!storage || !pathname) {
return
}
scrollHistory[pathname] = {
x: element == null ? window.scrollX : element.scrollLeft,
y: element == null ? window.scrollY : element.scrollTop,
}
storage.setItem("routeScrollPos", JSON.stringify(scrollHistory))
}
function getCurrentScrollPos() {
const path = browserHistory.getPath(browserHistory.browserHistory)
let scrollPos = {}
if (path) {
scrollPos = scrollHistory[path] || {}
}
return {
x: 0,
y: 0,
...scrollPos,
}
}
export function restoreScrollPosition(shouldRestore, element) {
if (!initialized) {
Polarisunexpected(
"you should disableNativeScrollRestoration in your router"
)
}
if (
!ExecutionEnvironment.canUseDOM ||
!document.querySelectorAll("#react-root > *")
) {
return
}
const scrollPos = shouldRestore
? getCurrentScrollPos()
: {
x: 0,
y: 0,
}
const xPos = scrollPos.x
const yPos = scrollPos.y
if (element == null) {
if (!document.fullscreenElement) {
window.scrollTo(xPos, yPos)
}
} else {
element.scrollLeft = xPos
element.scrollTop = yPos
}
}
function featureFlagEnabled() {
return qex._("186") === true
}
export function shouldRestoreScroll(history) {
if (history.action === browserHistory.ACTION.POP) {
return true
}
if (history.location.state?.scrollRestore) {
return true
}
if (
window.location.pathname === PolarisRoutes.FEED_PATH &&
featureFlagEnabled()
) {
return true
}
return false
}
export function restoreScrollPositionOnFullscreenExit() {
saveScrollPosition(browserHistory.browserHistory.location)
const listener = PolarisEventListener.add(
document,
"webkitfullscreenchange",
() => {
if (!document.fullscreenElement) {
listener.remove()
const currentPos = getCurrentScrollPos()
const xPos = currentPos.x
const yPos = currentPos.y
window.scrollTo(xPos, yPos)
}
}
)
}
import PolarisScrollPositionHistory from "PolarisScrollPositionHistory"
import browserHistory from "browserHistory"
import { useLayoutEffect } from "react"
export default function PolarisScrollPositionManager(el) {
const ref = el.container
useLayoutEffect(() => {
const element = ref?.current
if (element == null) {
return
}
const location = browserHistory.browserHistory.location
PolarisScrollPositionHistory.restoreScrollPosition(
PolarisScrollPositionHistory.shouldRestoreScroll(
browserHistory.browserHistory
),
element
)
return () => {
PolarisScrollPositionHistory.saveScrollPosition(location, element)
}
}, [ref])
return null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment