set reading progress percent to bottom position

This commit is contained in:
Jackson Harper 2023-03-10 14:50:45 +08:00
parent 2192c563a7
commit a0a144cdbd
3 changed files with 42 additions and 23 deletions

View file

@ -1,5 +1,8 @@
import { Box } from '../../elements/LayoutPrimitives'
import { useReadingProgressAnchor } from '../../../lib/hooks/useReadingProgressAnchor'
import {
getTopOmnivoreAnchorElement,
useReadingProgressAnchor,
} from '../../../lib/hooks/useReadingProgressAnchor'
import {
ScrollOffsetChangeset,
useScrollWatcher,
@ -26,25 +29,24 @@ export function Article(props: ArticleProps): JSX.Element {
props.initialReadingProgress
)
const [readingAnchorIndex, setReadingAnchorIndex] = useState(
props.initialAnchorIndex
)
const [shouldScrollToInitialPosition, setShouldScrollToInitialPosition] =
useState(true)
const articleContentRef = useRef<HTMLDivElement | null>(null)
useReadingProgressAnchor(articleContentRef, setReadingAnchorIndex)
useEffect(() => {
;(async () => {
if (!readingProgress) return
if (!articleContentRef.current) return
const anchor = getTopOmnivoreAnchorElement(articleContentRef.current)
const anchorIndex = Number(anchor)
await props.articleMutations.articleReadingProgressMutation({
id: props.articleId,
// round reading progress to 100% if more than that
readingProgressPercent: readingProgress > 100 ? 100 : readingProgress,
readingProgressAnchorIndex: readingAnchorIndex,
readingProgressAnchorIndex:
anchorIndex == Number.NaN ? undefined : anchorIndex,
})
})()
@ -65,24 +67,13 @@ export function Article(props: ArticleProps): JSX.Element {
useScrollWatcher((changeset: ScrollOffsetChangeset) => {
if (window && window.document.scrollingElement) {
const newReadingProgress =
const topProgress =
window.scrollY / window.document.scrollingElement.scrollHeight
const adjustedReadingProgress =
newReadingProgress > 0.92 ? 1 : newReadingProgress
const bottomProgress =
(window.scrollY + window.document.scrollingElement.clientHeight) /
window.document.scrollingElement.scrollHeight
console.log(
'newOffset Top: ',
newReadingProgress,
'newOffset Bottom: ',
bottomProgress,
window.scrollY,
window.document.scrollingElement.scrollHeight
)
setReadingProgress(adjustedReadingProgress * 100)
setReadingProgress(bottomProgress * 100)
}
}, 2500)

View file

@ -6,6 +6,34 @@ const ANCHOR_ELEMENTS_BLOCKED_ATTRIBUTES = [
'data-instagram-id',
]
// We search in reverse so we can find the last element
// that is visible on the page
export const getTopOmnivoreAnchorElement = (
articleContentElement: HTMLElement
): string | undefined => {
let lastVisibleAnchor: Element | undefined = undefined
const anchors = Array.from(
articleContentElement.querySelectorAll(`[data-omnivore-anchor-idx]`)
).reverse()
for (const anchor of anchors) {
const rect = anchor.getBoundingClientRect()
if (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= articleContentElement.clientHeight
) {
lastVisibleAnchor = anchor
} else if (lastVisibleAnchor) {
break
}
}
return (
lastVisibleAnchor?.getAttribute(`data-omnivore-anchor-idx`) ?? undefined
)
}
export const useReadingProgressAnchor = (
articleContentRef: React.MutableRefObject<HTMLDivElement | null>,
setReadingAnchorIndex: React.Dispatch<React.SetStateAction<number>>

View file

@ -3,8 +3,8 @@ import { gqlFetcher } from '../networkHelpers'
export type ArticleReadingProgressMutationInput = {
id: string
readingProgressPercent: number
readingProgressAnchorIndex: number
readingProgressPercent?: number
readingProgressAnchorIndex?: number
}
export async function articleReadingProgressMutation(