diff --git a/src/components/in-page/Note/NoteTimelineList/index.tsx b/src/components/in-page/Note/NoteTimelineList/index.tsx index db4a5149b..4c313da45 100644 --- a/src/components/in-page/Note/NoteTimelineList/index.tsx +++ b/src/components/in-page/Note/NoteTimelineList/index.tsx @@ -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' @@ -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' @@ -29,6 +30,26 @@ interface NoteTimelineListProps { noteId: string } +const TopicComp: FC<{ + note: NoteModel +}> = ({ note }) => { + const { event } = useAnalyze() + + return ( + + event({ + action: TrackerAction.Click, + label: `左侧时间线点击去话题页 - ${note?.topic?.name}`, + }) + } + > + {note?.topic?.name} + + ) +} + type NotePartial = Pick const ObserveredNoteTimelineList: FC< @@ -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( - () => ( - - event({ - action: TrackerAction.Click, - label: `左侧时间线点击去话题页 - ${note?.topic?.name}`, - }) - } - > - {note?.topic?.name} - - ), - [note?.topic?.name, note?.topic?.slug], + const triggerComponent = useMemo( + () => () => , + [note], ) const [animationParent] = useAutoAnimate() + return ( -
+
    {list?.map((item) => { @@ -99,7 +121,7 @@ const ObserveredNoteTimelineList: FC< placement="right" strategy="fixed" wrapperClassNames="flex flex-grow flex-shrink min-w-0" - triggerComponent={TopicComp} + triggerComponent={triggerComponent} > ) }) - +const scrollToTop = () => { + springScrollToTop(250) +} export const MemoedItem = memo<{ active: boolean item: NotePartial @@ -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} diff --git a/src/components/widgets/Subscribe/hooks.tsx b/src/components/widgets/Subscribe/hooks.tsx index 4e4a4cd23..fa3befa1f 100644 --- a/src/components/widgets/Subscribe/hooks.tsx +++ b/src/components/widgets/Subscribe/hooks.tsx @@ -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' @@ -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 diff --git a/src/utils/spring.ts b/src/utils/spring.ts index 62867ce5d..43fe78e81 100644 --- a/src/utils/spring.ts +++ b/src/utils/spring.ts @@ -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,