forked from Archives/Athou_commafeed
remove ScrollArea as it causes performance issues on chrome (#1087)
This commit is contained in:
@@ -94,7 +94,6 @@ export const Constants = {
|
|||||||
isBottomVisible: (div: HTMLElement) => div.getBoundingClientRect().bottom <= window.innerHeight,
|
isBottomVisible: (div: HTMLElement) => div.getBoundingClientRect().bottom <= window.innerHeight,
|
||||||
},
|
},
|
||||||
dom: {
|
dom: {
|
||||||
mainScrollAreaId: "main-scroll-area-id",
|
|
||||||
entryId: (entry: Entry) => `entry-id-${entry.id}`,
|
entryId: (entry: Entry) => `entry-id-${entry.id}`,
|
||||||
},
|
},
|
||||||
browserExtensionUrl: "https://github.com/Athou/commafeed-browser-extension",
|
browserExtensionUrl: "https://github.com/Athou/commafeed-browser-extension",
|
||||||
|
|||||||
@@ -204,18 +204,14 @@ export const selectEntry = createAsyncThunk<
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
|
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
|
||||||
const scrollArea = document.getElementById(Constants.dom.mainScrollAreaId)
|
scrollToWithCallback({
|
||||||
if (scrollArea) {
|
options: {
|
||||||
scrollToWithCallback({
|
// add a small gap between the top of the content and the top of the page
|
||||||
element: scrollArea,
|
top: entryElement.offsetTop - Constants.layout.headerHeight - 3,
|
||||||
options: {
|
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
||||||
// add a small gap between the top of the content and the top of the page
|
},
|
||||||
top: entryElement.offsetTop - 3,
|
onScrollEnded,
|
||||||
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
})
|
||||||
},
|
|
||||||
onScrollEnded,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectPreviousEntry = createAsyncThunk<
|
export const selectPreviousEntry = createAsyncThunk<
|
||||||
|
|||||||
@@ -26,30 +26,22 @@ export const calculatePlaceholderSize = ({ width, height, maxWidth }: { width?:
|
|||||||
return { width: placeholderWidth, height: placeholderHeight }
|
return { width: placeholderWidth, height: placeholderHeight }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const scrollToWithCallback = ({
|
export const scrollToWithCallback = ({ options, onScrollEnded }: { options: ScrollToOptions; onScrollEnded: () => void }) => {
|
||||||
element,
|
|
||||||
options,
|
|
||||||
onScrollEnded,
|
|
||||||
}: {
|
|
||||||
element: HTMLElement
|
|
||||||
options: ScrollToOptions
|
|
||||||
onScrollEnded: () => void
|
|
||||||
}) => {
|
|
||||||
const offset = (options.top ?? 0).toFixed()
|
const offset = (options.top ?? 0).toFixed()
|
||||||
|
|
||||||
const onScroll = () => {
|
const onScroll = () => {
|
||||||
if (element.offsetTop.toFixed() === offset) {
|
if (window.scrollY.toFixed() === offset) {
|
||||||
element.removeEventListener("scroll", onScroll)
|
window.removeEventListener("scroll", onScroll)
|
||||||
onScrollEnded()
|
onScrollEnded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
element.addEventListener("scroll", onScroll)
|
window.addEventListener("scroll", onScroll)
|
||||||
|
|
||||||
// scrollTo does not trigger if there's nothing to do, trigger it manually
|
// scrollTo does not trigger if there's nothing to do, trigger it manually
|
||||||
onScroll()
|
onScroll()
|
||||||
|
|
||||||
element.scrollTo(options)
|
window.scrollTo(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const truncate = (str: string, n: number) => (str.length > n ? `${str.slice(0, n - 1)}\u2026` : str)
|
export const truncate = (str: string, n: number) => (str.length > n ? `${str.slice(0, n - 1)}\u2026` : str)
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ export function FeedEntries() {
|
|||||||
const swipedRight = (entry: ExpendableEntry) => dispatch(markEntry({ entry, read: !entry.read }))
|
const swipedRight = (entry: ExpendableEntry) => dispatch(markEntry({ entry, read: !entry.read }))
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const scrollArea = document.getElementById(Constants.dom.mainScrollAreaId)
|
|
||||||
|
|
||||||
const listener = () => {
|
const listener = () => {
|
||||||
if (viewMode !== "expanded") return
|
if (viewMode !== "expanded") return
|
||||||
if (scrollingToEntry) return
|
if (scrollingToEntry) return
|
||||||
@@ -100,8 +98,8 @@ export function FeedEntries() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const throttledListener = throttle(100, listener)
|
const throttledListener = throttle(100, listener)
|
||||||
scrollArea?.addEventListener("scroll", throttledListener)
|
window.addEventListener("scroll", throttledListener)
|
||||||
return () => scrollArea?.removeEventListener("scroll", throttledListener)
|
return () => window.removeEventListener("scroll", throttledListener)
|
||||||
}, [dispatch, entries, viewMode, scrollMarks, scrollingToEntry])
|
}, [dispatch, entries, viewMode, scrollMarks, scrollingToEntry])
|
||||||
|
|
||||||
useMousetrap("r", () => dispatch(reloadEntries()))
|
useMousetrap("r", () => dispatch(reloadEntries()))
|
||||||
@@ -154,9 +152,8 @@ export function FeedEntries() {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
const scrollArea = document.getElementById(Constants.dom.mainScrollAreaId)
|
window.scrollTo({
|
||||||
scrollArea?.scrollTo({
|
top: window.scrollY + document.documentElement.clientHeight * 0.8,
|
||||||
top: scrollArea.scrollTop + scrollArea.clientHeight * 0.8,
|
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -193,9 +190,8 @@ export function FeedEntries() {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
const scrollArea = document.getElementById(Constants.dom.mainScrollAreaId)
|
window.scrollTo({
|
||||||
scrollArea?.scrollTo({
|
top: window.scrollY - document.documentElement.clientHeight * 0.8,
|
||||||
top: scrollArea.scrollTop - scrollArea.clientHeight * 0.8,
|
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -267,8 +263,6 @@ export function FeedEntries() {
|
|||||||
loadMore={() => dispatch(loadMoreEntries())}
|
loadMore={() => dispatch(loadMoreEntries())}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
loader={<Loader key={0} />}
|
loader={<Loader key={0} />}
|
||||||
useWindow={false}
|
|
||||||
getScrollParent={() => document.getElementById(Constants.dom.mainScrollAreaId)}
|
|
||||||
>
|
>
|
||||||
{entries.map(entry => (
|
{entries.map(entry => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Trans } from "@lingui/macro"
|
import { Trans } from "@lingui/macro"
|
||||||
import { createStyles, Group } from "@mantine/core"
|
import { createStyles, Group } from "@mantine/core"
|
||||||
import { Constants } from "app/constants"
|
|
||||||
import { markEntriesUpToEntry, markEntry, starEntry } from "app/slices/entries"
|
import { markEntriesUpToEntry, markEntry, starEntry } from "app/slices/entries"
|
||||||
import { redirectToFeed } from "app/slices/redirect"
|
import { redirectToFeed } from "app/slices/redirect"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { useAppDispatch, useAppSelector } from "app/store"
|
||||||
@@ -117,13 +116,11 @@ export function useFeedEntryContextMenu(entry: Entry) {
|
|||||||
|
|
||||||
// close context menu on scroll
|
// close context menu on scroll
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const scrollArea = document.getElementById(Constants.dom.mainScrollAreaId)
|
|
||||||
|
|
||||||
const listener = () => contextMenu.hideAll()
|
const listener = () => contextMenu.hideAll()
|
||||||
const throttledListener = throttle(100, listener)
|
const throttledListener = throttle(100, listener)
|
||||||
|
|
||||||
scrollArea?.addEventListener("scroll", throttledListener)
|
window.addEventListener("scroll", throttledListener)
|
||||||
return () => scrollArea?.removeEventListener("scroll", throttledListener)
|
return () => window.removeEventListener("scroll", throttledListener)
|
||||||
}, [contextMenu])
|
}, [contextMenu])
|
||||||
|
|
||||||
return { onContextMenu }
|
return { onContextMenu }
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
useMantineTheme,
|
useMantineTheme,
|
||||||
} from "@mantine/core"
|
} from "@mantine/core"
|
||||||
import { useViewportSize } from "@mantine/hooks"
|
|
||||||
import { Constants } from "app/constants"
|
import { Constants } from "app/constants"
|
||||||
import { redirectToAdd, redirectToRootCategory } from "app/slices/redirect"
|
import { redirectToAdd, redirectToRootCategory } from "app/slices/redirect"
|
||||||
import { reloadTree, setMobileMenuOpen, setSidebarWidth } from "app/slices/tree"
|
import { reloadTree, setMobileMenuOpen, setSidebarWidth } from "app/slices/tree"
|
||||||
@@ -91,7 +90,6 @@ function LogoAndTitle() {
|
|||||||
export default function Layout(props: LayoutProps) {
|
export default function Layout(props: LayoutProps) {
|
||||||
const { classes } = useStyles(props)
|
const { classes } = useStyles(props)
|
||||||
const theme = useMantineTheme()
|
const theme = useMantineTheme()
|
||||||
const viewport = useViewportSize()
|
|
||||||
const { loading } = useAppLoading()
|
const { loading } = useAppLoading()
|
||||||
const mobile = useMobile()
|
const mobile = useMobile()
|
||||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||||
@@ -197,18 +195,11 @@ export default function Layout(props: LayoutProps) {
|
|||||||
</Header>
|
</Header>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ScrollArea
|
<Box id="content" className={classes.mainContent}>
|
||||||
sx={{ height: viewport.height - Constants.layout.headerHeight }}
|
<Suspense fallback={<Loader />}>
|
||||||
viewportRef={ref => {
|
<Outlet />
|
||||||
if (ref) ref.id = Constants.dom.mainScrollAreaId
|
</Suspense>
|
||||||
}}
|
</Box>
|
||||||
>
|
|
||||||
<Box id="content" className={classes.mainContent}>
|
|
||||||
<Suspense fallback={<Loader />}>
|
|
||||||
<Outlet />
|
|
||||||
</Suspense>
|
|
||||||
</Box>
|
|
||||||
</ScrollArea>
|
|
||||||
</AppShell>
|
</AppShell>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user