mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
fix scrolling for "j" and "k" keyboard shortcuts
This commit is contained in:
@@ -26,6 +26,7 @@ export function FeedEntries() {
|
|||||||
const selectedEntryId = useAppSelector(state => state.entries.selectedEntryId)
|
const selectedEntryId = useAppSelector(state => state.entries.selectedEntryId)
|
||||||
const hasMore = useAppSelector(state => state.entries.hasMore)
|
const hasMore = useAppSelector(state => state.entries.hasMore)
|
||||||
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
||||||
|
const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
const selectedEntry = entries.find(e => e.id === selectedEntryId)
|
const selectedEntry = entries.find(e => e.id === selectedEntryId)
|
||||||
@@ -40,6 +41,20 @@ export function FeedEntries() {
|
|||||||
})
|
})
|
||||||
}, [entries])
|
}, [entries])
|
||||||
|
|
||||||
|
// scroll to entry when selected entry changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (!selectedEntryId) return
|
||||||
|
|
||||||
|
const selectedEntryElement = refs.current[selectedEntryId]
|
||||||
|
if (Constants.layout.isTopVisible(selectedEntryElement) && Constants.layout.isBottomVisible(selectedEntryElement)) return
|
||||||
|
|
||||||
|
document.getElementById(Constants.dom.mainScrollAreaId)?.scrollTo({
|
||||||
|
// having a small gap between the top of the content and the top of the page is sexier
|
||||||
|
top: selectedEntryElement.offsetTop - 3,
|
||||||
|
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
||||||
|
})
|
||||||
|
}, [selectedEntryId, scrollSpeed])
|
||||||
|
|
||||||
useMousetrap("r", () => {
|
useMousetrap("r", () => {
|
||||||
dispatch(reloadEntries())
|
dispatch(reloadEntries())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
|
import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
|
||||||
import { useDidUpdate } from "@mantine/hooks"
|
|
||||||
import { Constants } from "app/constants"
|
import { Constants } from "app/constants"
|
||||||
import { markEntry, selectEntry } from "app/slices/entries"
|
import { markEntry, selectEntry } from "app/slices/entries"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { useAppDispatch, useAppSelector } from "app/store"
|
||||||
import { Entry } from "app/types"
|
import { Entry } from "app/types"
|
||||||
import React, { useRef } from "react"
|
import React from "react"
|
||||||
import { FeedEntryBody } from "./FeedEntryBody"
|
import { FeedEntryBody } from "./FeedEntryBody"
|
||||||
import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
|
import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
|
||||||
import { FeedEntryFooter } from "./FeedEntryFooter"
|
import { FeedEntryFooter } from "./FeedEntryFooter"
|
||||||
@@ -39,7 +38,6 @@ const useStyles = createStyles((theme, props: FeedEntryProps) => {
|
|||||||
export function FeedEntry(props: FeedEntryProps) {
|
export function FeedEntry(props: FeedEntryProps) {
|
||||||
const { classes } = useStyles(props)
|
const { classes } = useStyles(props)
|
||||||
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
||||||
const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed)
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const compactHeader = viewMode === "title" && !props.expanded
|
const compactHeader = viewMode === "title" && !props.expanded
|
||||||
|
|
||||||
@@ -56,49 +54,30 @@ export function FeedEntry(props: FeedEntryProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll to entry when expanded
|
|
||||||
// we use useDidUpdate to avoid scrolling towards all entries during initial load when viewMode is "expanded"
|
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
|
||||||
useDidUpdate(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!ref.current) return
|
|
||||||
if (!props.expanded) return
|
|
||||||
if (Constants.layout.isTopVisible(ref.current) && Constants.layout.isBottomVisible(ref.current)) return
|
|
||||||
|
|
||||||
document.getElementById(Constants.dom.mainScrollAreaId)?.scrollTo({
|
|
||||||
// having a small gap between the top of the content and the top of the page is sexier
|
|
||||||
top: ref.current.offsetTop - 3,
|
|
||||||
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}, [props.expanded, scrollSpeed])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref}>
|
<Paper shadow="xs" withBorder className={classes.paper}>
|
||||||
<Paper shadow="xs" withBorder className={classes.paper}>
|
<Anchor
|
||||||
<Anchor
|
variant="text"
|
||||||
variant="text"
|
href={props.entry.url}
|
||||||
href={props.entry.url}
|
target="_blank"
|
||||||
target="_blank"
|
rel="noreferrer"
|
||||||
rel="noreferrer"
|
onClick={headerClicked}
|
||||||
onClick={headerClicked}
|
onAuxClick={headerClicked}
|
||||||
onAuxClick={headerClicked}
|
>
|
||||||
>
|
<Box p="xs">
|
||||||
<Box p="xs">
|
{compactHeader && <FeedEntryCompactHeader entry={props.entry} />}
|
||||||
{compactHeader && <FeedEntryCompactHeader entry={props.entry} />}
|
{!compactHeader && <FeedEntryHeader entry={props.entry} expanded={props.expanded} />}
|
||||||
{!compactHeader && <FeedEntryHeader entry={props.entry} expanded={props.expanded} />}
|
</Box>
|
||||||
|
</Anchor>
|
||||||
|
{props.expanded && (
|
||||||
|
<Box px="xs" pb="xs">
|
||||||
|
<Box className={classes.body} sx={{ direction: props.entry.rtl ? "rtl" : "ltr" }}>
|
||||||
|
<FeedEntryBody entry={props.entry} />
|
||||||
</Box>
|
</Box>
|
||||||
</Anchor>
|
<Divider variant="dashed" my="xs" />
|
||||||
{props.expanded && (
|
<FeedEntryFooter entry={props.entry} />
|
||||||
<Box px="xs" pb="xs">
|
</Box>
|
||||||
<Box className={classes.body} sx={{ direction: props.entry.rtl ? "rtl" : "ltr" }}>
|
)}
|
||||||
<FeedEntryBody entry={props.entry} />
|
</Paper>
|
||||||
</Box>
|
|
||||||
<Divider variant="dashed" my="xs" />
|
|
||||||
<FeedEntryFooter entry={props.entry} />
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Paper>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user