fix: add `scrollSeekConfiguration`
Signed-off-by: Innei <i@innei.in>
This commit is contained in:
parent
1b615f79cf
commit
87c4cdabc7
|
|
@ -21,23 +21,23 @@ export const ArticleItemSkeleton = (
|
|||
<div className="relative h-[120px] rounded-md bg-theme-background text-zinc-700 transition-colors dark:text-neutral-400">
|
||||
<div className="relative z-[1]">
|
||||
<div className="group relative flex py-4 pl-3 pr-2">
|
||||
<div className="mr-2 size-5 animate-pulse rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-2 size-5 rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="-mt-0.5 line-clamp-4 flex-1 text-sm leading-tight">
|
||||
<div className="flex gap-1 text-[10px] font-bold text-zinc-400 dark:text-neutral-500">
|
||||
<div className="h-3 w-24 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-24 bg-gray-200 dark:bg-neutral-800" />
|
||||
<span>·</span>
|
||||
<div className="h-3 w-12 shrink-0 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-12 shrink-0 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="relative my-1 break-words font-medium">
|
||||
<div className="h-3.5 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1 h-3.5 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3.5 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1 h-3.5 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="mt-1.5 text-[13px] text-zinc-400 dark:text-neutral-500">
|
||||
<div className="h-3 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1 h-3 w-4/5 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1 h-3 w-4/5 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-2 size-20 animate-pulse overflow-hidden rounded bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="ml-2 size-20 overflow-hidden rounded bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,17 +23,17 @@ export const AudioItemSkeleton = (
|
|||
<div className="group relative flex py-4 pl-3 pr-2">
|
||||
<div className="-mt-0.5 line-clamp-4 flex-1 text-sm leading-tight">
|
||||
<div className="flex gap-1 text-[10px] font-bold text-zinc-400 dark:text-neutral-500">
|
||||
<div className="h-3 w-20 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-20 bg-gray-200 dark:bg-neutral-800" />
|
||||
<span>·</span>
|
||||
<div className="h-3 w-10 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-10 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="relative my-0.5 break-words font-medium">
|
||||
<div className="h-4 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-2 h-4 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-2 h-4 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative ml-2 size-20 shrink-0">
|
||||
<div className="mr-2 size-20 shrink-0 animate-pulse overflow-hidden rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-2 size-20 shrink-0 overflow-hidden rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -51,12 +51,20 @@ import {
|
|||
useState,
|
||||
} from "react"
|
||||
import { useHotkeys } from "react-hotkeys-hook"
|
||||
import type { VirtuosoHandle, VirtuosoProps } from "react-virtuoso"
|
||||
import type {
|
||||
ScrollSeekConfiguration,
|
||||
VirtuosoHandle,
|
||||
VirtuosoProps,
|
||||
} from "react-virtuoso"
|
||||
import { Virtuoso, VirtuosoGrid } from "react-virtuoso"
|
||||
|
||||
import { useEntriesByView, useEntryMarkReadHandler } from "./hooks"
|
||||
import { EntryItem, EntryItemSkeleton } from "./item"
|
||||
|
||||
const scrollSeekConfiguration: ScrollSeekConfiguration = {
|
||||
enter: (velocity) => Math.abs(velocity) > 500,
|
||||
exit: (velocity) => Math.abs(velocity) < 500,
|
||||
}
|
||||
export function EntryColumn() {
|
||||
const virtuosoRef = useRef<VirtuosoHandle>(null)
|
||||
const entries = useEntriesByView({
|
||||
|
|
@ -95,12 +103,16 @@ export function EntryColumn() {
|
|||
const virtuosoOptions = {
|
||||
components: {
|
||||
List: ListContent,
|
||||
|
||||
Footer: useCallback(() => {
|
||||
if (!isFetchingNextPage) return null
|
||||
return <EntryItemSkeleton view={view} />
|
||||
}, [isFetchingNextPage, view]),
|
||||
ScrollSeekPlaceholder: useCallback(
|
||||
() => <EntryItemSkeleton view={view} single />,
|
||||
[view],
|
||||
),
|
||||
},
|
||||
scrollSeekConfiguration,
|
||||
rangeChanged: (...args: any[]) => {
|
||||
handleMarkReadInRange &&
|
||||
// @ts-expect-error
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ function EntryItemImpl({
|
|||
onDoubleClick={handleDoubleClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
>
|
||||
|
||||
<ListItemHoverOverlay
|
||||
className={cn(views[view || 0].gridMode ? "inset-0" : "inset-y-1")}
|
||||
isActive={isActive}
|
||||
|
|
@ -220,18 +219,22 @@ const LoadingCircleFallback = (
|
|||
<LoadingCircle size="medium" />
|
||||
</div>
|
||||
)
|
||||
export const EntryItemSkeleton: FC<{ view: FeedViewType }> = memo(
|
||||
({ view }) => {
|
||||
const SkeletonItem = SkeletonItemMap[view]
|
||||
return SkeletonItem ?
|
||||
(
|
||||
<div className="flex flex-col">{createSkeletonItems(SkeletonItem)}</div>
|
||||
) :
|
||||
(
|
||||
LoadingCircleFallback
|
||||
)
|
||||
},
|
||||
)
|
||||
export const EntryItemSkeleton: FC<{
|
||||
view: FeedViewType
|
||||
single?: boolean
|
||||
}> = memo(({ view, single }) => {
|
||||
const SkeletonItem = SkeletonItemMap[view]
|
||||
if (single) {
|
||||
return SkeletonItem
|
||||
}
|
||||
return SkeletonItem ?
|
||||
(
|
||||
<div className="flex flex-col">{createSkeletonItems(SkeletonItem)}</div>
|
||||
) :
|
||||
(
|
||||
LoadingCircleFallback
|
||||
)
|
||||
})
|
||||
|
||||
const createSkeletonItems = (element: ReactNode) => {
|
||||
const children = [] as ReactNode[]
|
||||
|
|
|
|||
|
|
@ -19,16 +19,16 @@ export function NotificationItem({
|
|||
export const NotificationItemSkeleton = (
|
||||
<div className="relative z-[1] mx-auto w-full max-w-lg">
|
||||
<div className="group relative flex py-4 pl-3 pr-2">
|
||||
<div className="mr-2 size-5 shrink-0 animate-pulse overflow-hidden rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-2 size-5 shrink-0 overflow-hidden rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="-mt-0.5 line-clamp-4 flex-1 text-sm leading-tight">
|
||||
<div className="flex gap-1 text-[10px] font-bold text-zinc-400 dark:text-neutral-500">
|
||||
<div className="h-3 w-32 animate-pulse truncate bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-32 truncate bg-gray-200 dark:bg-neutral-800" />
|
||||
<span>·</span>
|
||||
<div className="h-3 w-12 shrink-0 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-12 shrink-0 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="relative my-0.5 break-words">
|
||||
<div className="h-4 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-2 h-4 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-2 h-4 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -51,18 +51,18 @@ export const PictureItemSkeleton = (
|
|||
<div className="p-1.5">
|
||||
<div className="relative flex gap-2 overflow-x-auto">
|
||||
<div className="relative flex aspect-square w-full shrink-0 items-center overflow-hidden rounded-md">
|
||||
<div className="size-full animate-pulse overflow-hidden rounded-none bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-full overflow-hidden rounded-none bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex-1 px-2 pb-3 pt-1 text-sm">
|
||||
<div className="relative mb-1 mt-1.5 truncate font-medium leading-none">
|
||||
<div className="h-4 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="mt-1 flex items-center gap-1 truncate text-[13px]">
|
||||
<div className="mr-0.5 size-4 animate-pulse rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-1/2 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-0.5 size-4 rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-1/2 bg-gray-200 dark:bg-neutral-800" />
|
||||
<span className="text-zinc-500">·</span>
|
||||
<div className="h-3 w-12 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-12 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -139,31 +139,31 @@ export const SocialMediaItemSkeleton = (
|
|||
<div className="relative m-auto w-[75ch] rounded-md bg-theme-background text-zinc-700 transition-colors dark:text-neutral-400">
|
||||
<div className="relative z-[1]">
|
||||
<div className="group relative flex py-4 pl-3 pr-2">
|
||||
<div className="mr-2 size-9 animate-pulse rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-2 size-9 rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="ml-2 min-w-0 flex-1">
|
||||
<div className="-mt-0.5 line-clamp-5 flex-1 text-sm">
|
||||
<div className="flex w-[calc(100%-10rem)] space-x-1">
|
||||
<div className="h-4 w-16 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-16 bg-gray-200 dark:bg-neutral-800" />
|
||||
<span className="text-zinc-500">·</span>
|
||||
<div className="h-4 w-12 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-12 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="relative mt-0.5 whitespace-pre-line text-base">
|
||||
<div className="h-4 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1.5 h-4 w-full animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1.5 h-4 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1.5 h-4 w-full bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mt-1.5 h-4 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2 flex gap-2 overflow-x-auto">
|
||||
<div className="size-28 animate-pulse overflow-hidden rounded bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-28 overflow-hidden rounded bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="invisible absolute right-1 top-1.5 opacity-0 duration-200 group-hover:visible group-hover:opacity-80">
|
||||
<div className="flex origin-right scale-90 items-center gap-1">
|
||||
<div className="size-8 animate-pulse justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 animate-pulse justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 animate-pulse justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 animate-pulse justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 animate-pulse justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="size-8 justify-center rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -144,18 +144,18 @@ export const VideoItemSkeleton = (
|
|||
<div className="p-1.5">
|
||||
<div className="w-full">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="aspect-video w-full shrink-0 animate-pulse overflow-hidden rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="aspect-video w-full shrink-0 overflow-hidden rounded-md bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex-1 px-2 pb-3 pt-1 text-sm">
|
||||
<div className="relative mb-1 mt-1.5 truncate font-medium leading-none">
|
||||
<div className="h-4 w-3/4 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-4 w-3/4 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
<div className="mt-1 flex items-center gap-1 truncate text-[13px]">
|
||||
<div className="mr-0.5 size-4 animate-pulse rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-1/2 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="mr-0.5 size-4 rounded-sm bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-1/2 bg-gray-200 dark:bg-neutral-800" />
|
||||
<span className="text-zinc-500">·</span>
|
||||
<div className="h-3 w-12 animate-pulse bg-gray-200 dark:bg-neutral-800" />
|
||||
<div className="h-3 w-12 bg-gray-200 dark:bg-neutral-800" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue