Skip to content

Commit

Permalink
fix(note): note timeline list flash if scroll down
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Feb 27, 2023
1 parent ab9f832 commit 3f2412f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 44 deletions.
108 changes: 67 additions & 41 deletions src/components/in-page/Note/NoteTimelineList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { clsx } from 'clsx'
import { observer } from 'mobx-react-lite'
import Link from 'next/link'
import type { FC } from 'react'
import { memo, useCallback } from 'react'
import useSWR from 'swr'
import { memo, useEffect, useMemo, useState } from 'react'

import { useAutoAnimate } from '@formkit/auto-animate/react'
import type { NoteModel } from '@mx-space/api-client'
Expand All @@ -19,8 +18,10 @@ import { LeftRightTransitionView } from '@mx-space/kami-design/components/Transi
import { ImpressionView } from '~/components/biz/ImpressionView'
import { TrackerAction } from '~/constants/tracker'
import { useAnalyze } from '~/hooks/use-analyze'
import { useIsUnMounted } from '~/hooks/use-is-unmounted'
import { useStore } from '~/store'
import { apiClient } from '~/utils/client'
import { springScrollToTop } from '~/utils/spring'

import { InnerTopicDetail } from '../NoteTopic/inner-detail'
import styles from './index.module.css'
Expand All @@ -29,6 +30,26 @@ interface NoteTimelineListProps {
noteId: string
}

const TopicComp: FC<{
note: NoteModel
}> = ({ note }) => {
const { event } = useAnalyze()

return (
<Link
href={`/notes/topics/${note?.topic?.slug}`}
onClick={() =>
event({
action: TrackerAction.Click,
label: `左侧时间线点击去话题页 - ${note?.topic?.name}`,
})
}
>
<span className="flex-grow truncate">{note?.topic?.name}</span>
</Link>
)
}

type NotePartial = Pick<NoteModel, 'id' | 'nid' | 'created' | 'title'>

const ObserveredNoteTimelineList: FC<
Expand All @@ -39,49 +60,50 @@ const ObserveredNoteTimelineList: FC<
const { noteStore } = useStore()
const note = noteStore.get(noteId)

const { data: list } = useSWR(
['note-topic', noteId],
([, noteId]) =>
apiClient.note.getMiddleList(noteId, 10).then(({ data }) => {
return data
}),
{
keepPreviousData: true,
fallbackData: note
? [
{
created: note.created,
id: note.id,
nid: note.nid,
title: note.title,
},
]
: [],
},
)
const [list, setList] = useState(() => {
if (!note) return []
return [
{
created: note.created,
id: note.id,
nid: note.nid,
title: note.title,
},
]
})

const { event } = useAnalyze()
const isUnmount = useIsUnMounted()
useEffect(() => {
async function fetchList() {
const scrollTop = document.documentElement.scrollTop

if (scrollTop > 0)
// waiting scroll to top
await new Promise((resolve) => setTimeout(resolve, 350))

if (isUnmount.current) return
const data = await apiClient.note
.getMiddleList(noteId, 10)
.then(({ data }) => {
return data
})
if (isUnmount.current) return

setList(data)
}
fetchList()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [noteId])

const TopicComp = useCallback(
() => (
<Link
href={`/notes/topics/${note?.topic?.slug}`}
onClick={() =>
event({
action: TrackerAction.Click,
label: `左侧时间线点击去话题页 - ${note?.topic?.name}`,
})
}
>
<span className="flex-grow truncate">{note?.topic?.name}</span>
</Link>
),
[note?.topic?.name, note?.topic?.slug],
const triggerComponent = useMemo(
() => () => <TopicComp note={note!} />,
[note],
)

const [animationParent] = useAutoAnimate<HTMLUListElement>()

return (
<div className={clsx(className, styles['container'])} data-hide-print>
<div className={clsx(styles['container'], className)} data-hide-print>
<div className={clsx(styles.list)}>
<ul ref={animationParent}>
{list?.map((item) => {
Expand All @@ -99,7 +121,7 @@ const ObserveredNoteTimelineList: FC<
placement="right"
strategy="fixed"
wrapperClassNames="flex flex-grow flex-shrink min-w-0"
triggerComponent={TopicComp}
triggerComponent={triggerComponent}
>
<ImpressionView
trackerMessage={`曝光 - 左侧时间线话题内页展开 - ${note?.topic?.name}`}
Expand All @@ -115,7 +137,9 @@ const ObserveredNoteTimelineList: FC<
</div>
)
})

const scrollToTop = () => {
springScrollToTop(250)
}
export const MemoedItem = memo<{
active: boolean
item: NotePartial
Expand All @@ -132,6 +156,8 @@ export const MemoedItem = memo<{
className={clsx(active ? styles['active'] : null, styles.item)}
href={`/notes/${item.nid}`}
key={item.id}
scroll={false}
onClick={scrollToTop}
>
{item.title}
</Link>
Expand Down
6 changes: 4 additions & 2 deletions src/components/widgets/Subscribe/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import useSWR from 'swr'

import { SubscribeTypeToBitMap } from '@mx-space/api-client'
import type { SubscribeTypeToBitMap } from '@mx-space/api-client'
import { useModalStack } from '@mx-space/kami-design'

import { TrackerAction } from '~/constants/tracker'
Expand All @@ -12,7 +12,9 @@ import { SubscribeModal } from './modal'
const SWR_CHECK_SUBSCRIBE_KEY = 'subscribe-status'

export const useSubscribeStatus = () => {
return useSWR(SWR_CHECK_SUBSCRIBE_KEY, apiClient.subscribe.check)
return useSWR(SWR_CHECK_SUBSCRIBE_KEY, apiClient.subscribe.check, {
refreshInterval: 10e8,
})
}

export const useIsEnableSubscribe = () => useSubscribeStatus().data?.enable
Expand Down
3 changes: 2 additions & 1 deletion src/utils/spring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export const genSpringKeyframes = (

return [name, css, keyframes] as const
}
export const springScrollToTop = () => springScrollTo(0)
export const springScrollToTop = (duration?: number) =>
springScrollTo(0, duration)
export const springScrollTo = (
to: number,
duration = 1000,
Expand Down

0 comments on commit 3f2412f

Please sign in to comment.