@@ -8,7 +8,7 @@ import { MotionButtonBase } from "@follow/components/ui/button/index.js"
8
8
import { RootPortal } from "@follow/components/ui/portal/index.js"
9
9
import { ScrollArea } from "@follow/components/ui/scroll-area/index.js"
10
10
import type { FeedViewType } from "@follow/constants"
11
- import { useTitle } from "@follow/hooks"
11
+ import { useSmoothScroll , useTitle } from "@follow/hooks"
12
12
import type { FeedModel , InboxModel } from "@follow/models/types"
13
13
import { nextFrame , stopPropagation } from "@follow/utils/dom"
14
14
import { EventBus } from "@follow/utils/event-bus"
@@ -17,7 +17,7 @@ import { ErrorBoundary } from "@sentry/react"
17
17
import type { JSAnimation , Variants } from "motion/react"
18
18
import { AnimatePresence , m , useAnimationControls } from "motion/react"
19
19
import * as React from "react"
20
- import { useCallback , useEffect , useMemo , useRef , useState } from "react"
20
+ import { useEffect , useMemo , useRef , useState } from "react"
21
21
22
22
import { useEntryIsInReadability } from "~/atoms/readability"
23
23
import { useIsZenMode , useUISettingKey } from "~/atoms/settings/ui"
@@ -247,7 +247,7 @@ const EntryScrollArea: Component<{
247
247
}
248
248
return (
249
249
< ScrollArea . ScrollArea
250
- focusable = { false }
250
+ focusable
251
251
mask = { false }
252
252
rootClassName = { cn (
253
253
"h-0 min-w-0 grow overflow-y-auto print:h-auto print:overflow-visible" ,
@@ -346,65 +346,7 @@ const RegisterCommands = ({
346
346
} )
347
347
348
348
const { highlightBoundary } = useFocusActions ( )
349
-
350
- // Smooth scroll implementation similar to Vimium
351
- const smoothScrollTo = useCallback (
352
- ( targetScrollTop : number , element : HTMLDivElement ) => {
353
- // Stop any existing animation
354
- if ( scrollAnimationRef . current ) {
355
- scrollAnimationRef . current . stop ( )
356
- }
357
-
358
- const startScrollTop = element . scrollTop
359
- const distance = targetScrollTop - startScrollTop
360
-
361
- // If distance is very small, just set it directly
362
- if ( Math . abs ( distance ) < 1 ) {
363
- element . scrollTop = targetScrollTop
364
- scrollAnimationRef . current = null
365
- return
366
- }
367
-
368
- // Adaptive duration based on distance - shorter for small distances, longer for large ones
369
- const baseDuration = 150
370
- const maxDuration = 300
371
- const duration = Math . min ( maxDuration , baseDuration + Math . abs ( distance ) * 0.5 )
372
- const startTime = performance . now ( )
373
-
374
- // Easing function similar to Vimium's smooth scrolling - ease out cubic for natural feel
375
- const easeOutCubic = ( t : number ) : number => {
376
- return 1 - Math . pow ( 1 - t , 3 )
377
- }
378
-
379
- let animationId : number
380
-
381
- const animateScroll = ( currentTime : number ) => {
382
- const elapsed = currentTime - startTime
383
- const progress = Math . min ( elapsed / duration , 1 )
384
-
385
- const easedProgress = easeOutCubic ( progress )
386
- const currentScrollTop = startScrollTop + distance * easedProgress
387
-
388
- element . scrollTop = currentScrollTop
389
-
390
- if ( progress < 1 ) {
391
- animationId = requestAnimationFrame ( animateScroll )
392
- scrollAnimationRef . current = {
393
- stop : ( ) => {
394
- cancelAnimationFrame ( animationId )
395
- scrollAnimationRef . current = null
396
- } ,
397
- } as any
398
- } else {
399
- scrollAnimationRef . current = null
400
- }
401
- }
402
-
403
- animationId = requestAnimationFrame ( animateScroll )
404
- } ,
405
- [ scrollAnimationRef ] ,
406
- )
407
-
349
+ const smoothScrollTo = useSmoothScroll ( )
408
350
useEffect ( ( ) => {
409
351
const checkScrollBottom = ( $scroller : HTMLDivElement ) => {
410
352
const currentScroll = $scroller . scrollTop
0 commit comments