fix(entry-column): remove entry item should calculate layout

- Introduced EntryVirtualListItem to enhance the rendering of entries in a virtualized list.
- Updated EntryList to utilize EntryVirtualListItem, improving performance and structure.
- Removed redundant keydown handling logic from EntryList, streamlining the component.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-04-18 23:14:36 +08:00
parent 3566b8ef27
commit fd29975cf9
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
2 changed files with 29 additions and 20 deletions

View File

@ -3,7 +3,7 @@ import type { FeedViewType } from "@follow/constants"
import { views } from "@follow/constants"
import { cn } from "@follow/utils/utils"
import type { FC } from "react"
import { memo } from "react"
import { forwardRef, memo } from "react"
import { useEntryTranslation } from "~/store/ai/hook"
import type { FlatEntryModel } from "~/store/entry"
@ -37,6 +37,21 @@ export const EntryItem: FC<EntryItemProps> = memo(({ entryId, view }) => {
return <EntryItemImpl entry={entry} view={view} />
})
export const EntryVirtualListItem = forwardRef<
HTMLDivElement,
EntryItemProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
>(({ entryId, view, className, ...props }, ref) => {
const entry = useEntry(entryId)
if (!entry) return <div ref={ref} {...props} style={undefined} />
return (
<div className="absolute left-0 top-0 w-full will-change-transform" ref={ref} {...props}>
<EntryItemImpl entry={entry} view={view} />
</div>
)
})
const LoadingCircleFallback = (
<div className="center mt-2">
<LoadingCircle size="medium" />

View File

@ -13,7 +13,6 @@ import {
Fragment,
memo,
startTransition,
useCallback,
useEffect,
useMemo,
useRef,
@ -30,11 +29,7 @@ import { isListSubscription } from "~/store/subscription"
import { DateItem } from "./components/DateItem"
import { EntryColumnShortcutHandler } from "./EntryColumnShortcutHandler"
import { EntryItem, EntryItemSkeleton } from "./item"
export const EntryListContent = forwardRef<HTMLDivElement>((props, ref) => (
<div className="px-2" {...props} ref={ref} />
))
import { EntryItemSkeleton, EntryVirtualListItem } from "./item"
export const EntryEmptyList = forwardRef<HTMLDivElement, HTMLMotionProps<"div">>((props, ref) => {
const unreadOnly = useGeneralSettingKey("unreadOnly")
@ -82,6 +77,12 @@ export type EntryListProps = {
const capacity = 3
const offsetCache = new LRUCache<string, number>(capacity)
const measurementsCache = new LRUCache<string, VirtualItem[]>(capacity)
// Prevent scroll list move when press up/down key, the up/down key should be taken over by the shortcut key we defined.
const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (e) => {
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
e.preventDefault()
}
}
export const EntryList: FC<EntryListProps> = memo(
({
feedId,
@ -96,13 +97,6 @@ export const EntryList: FC<EntryListProps> = memo(
onRangeChange,
gap,
}) => {
// Prevent scroll list move when press up/down key, the up/down key should be taken over by the shortcut key we defined.
const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useCallback((e) => {
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
e.preventDefault()
}
}, [])
const scrollRef = useScrollViewElement()
const stickyIndexes = useMemo(
@ -268,17 +262,17 @@ export const EntryList: FC<EntryListProps> = memo(
/>
</div>
)}
<div
className="absolute left-0 top-0 w-full will-change-transform"
<EntryVirtualListItem
entryId={entriesIds[virtualRow.index]!}
view={view}
data-index={virtualRow.index}
style={{
transform,
paddingTop: isStickyItem ? "1.75rem" : undefined,
}}
ref={rowVirtualizer.measureElement}
data-index={virtualRow.index}
>
<EntryItem entryId={entriesIds[virtualRow.index]!} view={view} />
</div>
/>
</Fragment>
)
})}