Skip to content

Commit df5d8ba

Browse files
committed
feat: peek link
Signed-off-by: Innei <[email protected]>
1 parent d4a9838 commit df5d8ba

File tree

5 files changed

+85
-56
lines changed

5 files changed

+85
-56
lines changed

src/app/timeline/page.tsx

+5-52
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
'use client'
22

33
import { useQuery } from '@tanstack/react-query'
4-
import { memo, useCallback, useEffect } from 'react'
4+
import { memo, useEffect } from 'react'
55
import clsx from 'clsx'
66
import { m } from 'framer-motion'
7-
import Link from 'next/link'
87
import { useRouter, useSearchParams } from 'next/navigation'
98
import type { TimelineData } from '@mx-space/api-client'
10-
import type { SyntheticEvent } from 'react'
119

1210
import { TimelineType } from '@mx-space/api-client'
1311

@@ -17,13 +15,10 @@ import { NormalContainer } from '~/components/layout/container/Normal'
1715
import { Divider } from '~/components/ui/divider'
1816
import { TimelineList } from '~/components/ui/list/TimelineList'
1917
import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
20-
import { NotePreview } from '~/components/widgets/peek/NotePreview'
21-
import { PeekModal } from '~/components/widgets/peek/PeekModal'
22-
import { PostPreview } from '~/components/widgets/peek/PostPreview'
18+
import { PeekLink } from '~/components/widgets/peek/PeekLink'
2319
import { TimelinProgress } from '~/components/widgets/timeline/TimelineProgress'
2420
import { apiClient } from '~/lib/request'
2521
import { springScrollToElement } from '~/lib/scroller'
26-
import { useModalStack } from '~/providers/root/modal-stack-provider'
2722

2823
enum ArticleType {
2924
Post,
@@ -221,48 +216,7 @@ const Item = memo<{
221216
}>(({ item }) => {
222217
const router = useRouter()
223218
const isMobile = useIsMobile()
224-
const { present } = useModalStack()
225-
226-
const handlePeek = useCallback(
227-
(e: SyntheticEvent) => {
228-
if (isMobile) return
229-
if (item.type === ArticleType.Note) {
230-
{
231-
e.preventDefault()
232-
present({
233-
clickOutsideToDismiss: true,
234-
title: 'Preview',
235-
modalClassName: 'flex justify-center',
236-
modalContainerClassName: 'flex justify-center',
237-
CustomModalComponent: () => (
238-
<PeekModal to={item.href}>
239-
<NotePreview noteId={parseInt(item.href.split('/').pop()!)} />
240-
</PeekModal>
241-
),
242-
content: () => null,
243-
})
244-
}
245-
} else if (item.type === ArticleType.Post) {
246-
e.preventDefault()
247-
const splitpath = item.href.split('/')
248-
const slug = splitpath.pop()!
249-
const category = splitpath.pop()!
250-
present({
251-
clickOutsideToDismiss: true,
252-
title: 'Preview',
253-
modalClassName: 'flex justify-center',
254-
modalContainerClassName: 'flex justify-center',
255-
CustomModalComponent: () => (
256-
<PeekModal to={item.href}>
257-
<PostPreview category={category} slug={slug} />
258-
</PeekModal>
259-
),
260-
content: () => null,
261-
})
262-
}
263-
},
264-
[isMobile],
265-
)
219+
266220
return (
267221
<li
268222
key={item.id}
@@ -276,14 +230,13 @@ const Item = memo<{
276230
day: '2-digit',
277231
}).format(item.date)}
278232
</span>
279-
<Link
233+
<PeekLink
280234
prefetch={false}
281235
href={item.href}
282236
className="min-w-0 truncate leading-6"
283-
onClick={handlePeek}
284237
>
285238
<span className="min-w-0 truncate">{item.title}</span>
286-
</Link>
239+
</PeekLink>
287240
{item.important && (
288241
<SolidBookmark
289242
className="ml-2 cursor-pointer text-red-500"

src/components/layout/header/internal/Activity.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ export function Activity() {
7676
refetchInterval: 5000,
7777
retry: false,
7878
enabled: isEnabled,
79+
meta: {
80+
persist: false,
81+
},
7982
},
8083
)
8184
const ownerName = useAggregationSelector((data) => data.user.name)

src/components/layout/header/internal/SiteOwnerAvatar.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export const SiteOwnerAvatar: Component = ({ className }) => {
2121
return !!data
2222
}, []),
2323
refetchInterval: 1000 * 60,
24+
meta: {
25+
persist: false,
26+
},
2427
})
2528

2629
const handleGoLive = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { useCallback } from 'react'
2+
import Link from 'next/link'
3+
import type { LinkProps } from 'next/link'
4+
import type { FC, PropsWithChildren, SyntheticEvent } from 'react'
5+
6+
import { useIsMobile } from '~/atoms'
7+
import { useModalStack } from '~/providers/root/modal-stack-provider'
8+
9+
import { NotePreview } from './NotePreview'
10+
import { PeekModal } from './PeekModal'
11+
import { PostPreview } from './PostPreview'
12+
13+
export const PeekLink: FC<
14+
{
15+
href: string
16+
} & LinkProps &
17+
PropsWithChildren &
18+
React.AnchorHTMLAttributes<HTMLAnchorElement>
19+
> = (props) => {
20+
const { href, children, ...rest } = props
21+
const isMobile = useIsMobile()
22+
const { present } = useModalStack()
23+
const handlePeek = useCallback(
24+
(e: SyntheticEvent) => {
25+
if (isMobile) return
26+
27+
if (href.startsWith('/notes/')) {
28+
{
29+
e.preventDefault()
30+
present({
31+
clickOutsideToDismiss: true,
32+
title: 'Preview',
33+
modalClassName: 'flex justify-center',
34+
modalContainerClassName: 'flex justify-center',
35+
CustomModalComponent: () => (
36+
<PeekModal to={href}>
37+
<NotePreview noteId={parseInt(href.split('/').pop()!)} />
38+
</PeekModal>
39+
),
40+
content: () => null,
41+
})
42+
}
43+
} else if (href.startsWith('/posts/')) {
44+
e.preventDefault()
45+
const splitpath = href.split('/')
46+
const slug = splitpath.pop()!
47+
const category = splitpath.pop()!
48+
present({
49+
clickOutsideToDismiss: true,
50+
title: 'Preview',
51+
modalClassName: 'flex justify-center',
52+
modalContainerClassName: 'flex justify-center',
53+
CustomModalComponent: () => (
54+
<PeekModal to={href}>
55+
<PostPreview category={category} slug={slug} />
56+
</PeekModal>
57+
),
58+
content: () => null,
59+
})
60+
}
61+
},
62+
[href, isMobile, present],
63+
)
64+
65+
return (
66+
<Link href={href} onClick={handlePeek} {...rest}>
67+
{children}
68+
</Link>
69+
)
70+
}

src/components/widgets/post/PostRelated.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
'use client'
22

3-
import Link from 'next/link'
4-
53
import { Divider } from '~/components/ui/divider'
64
import { useCurrentPostDataSelector } from '~/providers/post/CurrentPostDataProvider'
75

6+
import { PeekLink } from '../peek/PeekLink'
7+
88
export const PostRelated = () => {
99
const related = useCurrentPostDataSelector((s) => s?.related)
1010
if (!related) {
@@ -24,12 +24,12 @@ export const PostRelated = () => {
2424
{related.map((post) => {
2525
return (
2626
<li key={post.id}>
27-
<Link
27+
<PeekLink
2828
href={`/posts/${post.category.slug}/${post.slug}`}
2929
className="underline-current underline-dashed leading-10 underline"
3030
>
3131
{post.title}
32-
</Link>
32+
</PeekLink>
3333
</li>
3434
)
3535
})}

0 commit comments

Comments
 (0)