Skip to content

Commit

Permalink
refactor: use jotai to hold post data
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Jun 23, 2023
1 parent 561c2e9 commit bac61bb
Show file tree
Hide file tree
Showing 22 changed files with 196 additions and 187 deletions.
2 changes: 1 addition & 1 deletion src/app/notes/[id]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpT
import { REQUEST_QUERY } from '~/constants/system'
import { attachUA } from '~/lib/attach-ua'
import { getSummaryFromMd } from '~/lib/markdown'
import { CurrentNoteDataProvider } from '~/providers/note/CurrentNodeDataProvider'
import { CurrentNoteDataProvider } from '~/providers/note/CurrentNoteDataProvider'
import { CurrentNoteIdProvider } from '~/providers/note/CurrentNoteIdProvider'
import { queries } from '~/queries/definition'
import { getQueryClient } from '~/utils/query-client.server'
Expand Down
2 changes: 1 addition & 1 deletion src/app/notes/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Markdown } from '~/components/ui/markdown'
import { XLogInfoForNote, XLogSummaryForNote } from '~/components/widgets/xlog'
import { noopArr } from '~/lib/noop'
import { MarkdownImageRecordProvider } from '~/providers/article/MarkdownImageRecordProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentNoteId } from '~/providers/note/CurrentNoteIdProvider'
import { LayoutRightSidePortal } from '~/providers/shared/LayoutRightSideProvider'
import { WrappedElementProvider } from '~/providers/shared/WrappedElementProvider'
Expand Down
9 changes: 5 additions & 4 deletions src/app/posts/(post-detail)/[category]/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import type { Metadata } from 'next'

import { QueryHydration } from '~/components/common/QueryHydration'
import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
import { attachUA } from '~/lib/attach-ua'
import { getSummaryFromMd } from '~/lib/markdown'
import { CurrentPostDataProvider } from '~/providers/post/CurrentPostDataProvider'
import { LayoutRightSideProvider } from '~/providers/shared/LayoutRightSideProvider'
import { queries } from '~/queries/definition'
import { getQueryClient } from '~/utils/query-client.server'
Expand Down Expand Up @@ -61,17 +61,18 @@ export default async (props: NextPageParams<PageParams>) => {
params: { category, slug },
} = props
const query = queries.post.bySlug(category, slug)
const queryKey = query.queryKey
// const queryKey = query.queryKey
const data = await getQueryClient().fetchQuery(query)
return (
<QueryHydration queryKey={queryKey} data={data}>
<>
<CurrentPostDataProvider data={data} />
<div className="relative flex min-h-[120px] grid-cols-[auto,200px] lg:grid">
<BottomToUpTransitionView className="min-w-0">
{props.children}
</BottomToUpTransitionView>

<LayoutRightSideProvider className="relative hidden lg:block" />
</div>
</QueryHydration>
</>
)
}
75 changes: 45 additions & 30 deletions src/app/posts/(post-detail)/[category]/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import { useEffect } from 'react'
import { Balancer } from 'react-wrap-balancer'
import type { Image, PostModel } from '@mx-space/api-client'
import type { Image } from '@mx-space/api-client'
import type { PropsWithChildren } from 'react'

import { ReadIndicator } from '~/components/common/ReadIndicator'
import { useSetHeaderMetaInfo } from '~/components/layout/header/hooks'
Expand All @@ -12,63 +13,77 @@ import { PostMetaBar } from '~/components/widgets/post/PostMetaBar'
import { SubscribeBell } from '~/components/widgets/subscribe/SubscribeBell'
import { TocAside, TocAutoScroll } from '~/components/widgets/toc'
import { XLogInfoForPost, XLogSummaryForPost } from '~/components/widgets/xlog'
import { useCurrentPostData } from '~/hooks/data/use-post'
import { noopArr } from '~/lib/noop'
import { MarkdownImageRecordProvider } from '~/providers/article/MarkdownImageRecordProvider'
import { useCurrentPostDataSelector } from '~/providers/post/CurrentPostDataProvider'
import { LayoutRightSidePortal } from '~/providers/shared/LayoutRightSideProvider'
import { WrappedElementProvider } from '~/providers/shared/WrappedElementProvider'

import Loading from './loading'

const useHeaderMeta = (data?: PostModel | null) => {
const setHeader = useSetHeaderMetaInfo()
useEffect(() => {
if (!data) return
setHeader({
const PostMarkdown = () => {
const text = useCurrentPostDataSelector((data) => data?.text)
if (!text) return null

return <Markdown value={text} as="main" className="min-w-0 overflow-hidden" />
}
const PostMarkdownImageRecordProvider = (props: PropsWithChildren) => {
const images = useCurrentPostDataSelector(
(data) => data?.images || (noopArr as Image[]),
)
if (!images) return null

return (
<MarkdownImageRecordProvider images={images}>
{props.children}
</MarkdownImageRecordProvider>
)
}

const HeaderMetaInfoSetting = () => {
const setHeaderMetaInfo = useSetHeaderMetaInfo()
const meta = useCurrentPostDataSelector((data) => {
if (!data) return null

return {
title: data.title,
description:
data.category.name +
(data.tags.length > 0 ? ` / ${data.tags.join(', ')}` : ''),
slug: `${data.category.slug}/${data.slug}`,
})
}, [
data?.title,
data?.category.name,
data?.tags.length,
data?.category.slug,
data?.slug,
])
}
})

useEffect(() => {
if (meta) setHeaderMetaInfo(meta)
}, [meta])

return null
}
const PostPage = () => {
const data = useCurrentPostData()

useHeaderMeta(data)
if (!data) {
const id = useCurrentPostDataSelector((p) => p?.id)
const title = useCurrentPostDataSelector((p) => p?.title)
if (!id) {
return <Loading />
}

return (
<div>
<HeaderMetaInfoSetting />
<article className="prose">
<header className="mb-8">
<h1 className="text-center">
<Balancer>{data.title}</Balancer>
<Balancer>{title}</Balancer>
</h1>

<PostMetaBar data={data} className="mb-8 justify-center" />
<PostMetaBar className="mb-8 justify-center" />

<XLogSummaryForPost />
</header>
<WrappedElementProvider>
<MarkdownImageRecordProvider
images={data.images || (noopArr as Image[])}
>
<Markdown
value={data.text}
as="main"
className="min-w-0 overflow-hidden"
/>
</MarkdownImageRecordProvider>
<PostMarkdownImageRecordProvider>
<PostMarkdown />
</PostMarkdownImageRecordProvider>

<LayoutRightSidePortal>
<TocAside
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteActionAside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
getCurrentNoteData,
setCurrentNoteData,
useCurrentNoteDataSelector,
} from '~/providers/note/CurrentNodeDataProvider'
} from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentNoteId } from '~/providers/note/CurrentNoteIdProvider'
import { useAggregationData } from '~/providers/root/aggregation-data-provider'
import { isLikedBefore, setLikeId } from '~/utils/cookie'
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteFooterNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MdiClockTimeThreeOutline } from '~/components/icons/clock'
import { Divider } from '~/components/ui/divider'
import { OnlyMobile } from '~/components/ui/viewport/OnlyMobile'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
import { springScrollToTop } from '~/utils/scroller'

export const NoteFooterNavigation: FC<{ noteId: string }> = ({
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteHideIfSecret.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import dayjs from 'dayjs'

import { useIsLogged } from '~/atoms/owner'
import { toast } from '~/lib/toast'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentNoteId } from '~/providers/note/CurrentNoteIdProvider'

export const NoteHideIfSecret: Component = ({ children }) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteMetaBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { CreativeCommonsIcon } from '~/components/icons/cc'
import { DividerVertical } from '~/components/ui/divider'
import { mood2icon, weather2icon } from '~/lib/meta-icon'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'

const dividerVertical = <DividerVertical className="!mx-2 scale-y-50" />

Expand Down
4 changes: 3 additions & 1 deletion src/components/widgets/note/NoteTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { tv } from 'tailwind-variants'

import { LeftToRightTransitionView } from '~/components/ui/transition/LeftToRightTransitionView'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { getCurrentNoteData } from '~/providers/note/CurrentNodeDataProvider'
import { getCurrentNoteData } from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentNoteId } from '~/providers/note/CurrentNoteIdProvider'
import { clsxm } from '~/utils/helper'
import { apiClient } from '~/utils/request'
import { springScrollToTop } from '~/utils/scroller'

export const NoteTimeline = () => {
const noteId = useCurrentNoteId()
Expand Down Expand Up @@ -99,6 +100,7 @@ const MemoedItem = memo<{
<i className="icon-[material-symbols--arrow-circle-right-outline-rounded] duration-200" />
</LeftToRightTransitionView>
<Link
onClick={springScrollToTop}
prefetch={false}
className={clsxm(
active
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteTopic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Avatar } from '~/components/ui/avatar'
import { Divider } from '~/components/ui/divider'
import { FloatPopover } from '~/components/ui/float-popover'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'

import { NoteTopicDetail } from './NoteTopicDetail'
import { NoteTopicMarkdownRender } from './NoteTopicMarkdownRender'
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteTopicDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Loading } from '~/components/ui/loading'
import { RelativeTime } from '~/components/ui/relative-time'
import { useIsClient } from '~/hooks/common/use-is-client'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
import { apiClient } from '~/utils/request'

import { NoteTopicMarkdownRender } from './NoteTopicMarkdownRender'
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteTopicInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Divider } from '~/components/ui/divider'
import { FloatPopover } from '~/components/ui/float-popover'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'

import { NoteTopicDetail, ToTopicLink } from './NoteTopicDetail'

Expand Down
32 changes: 13 additions & 19 deletions src/components/widgets/post/PostActionAside.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
'use client'

import { useQueryClient } from '@tanstack/react-query'
import { motion, useAnimationControls, useForceUpdate } from 'framer-motion'
import { produce } from 'immer'
import type { NoteWrappedPayload } from '@mx-space/api-client'

import { IonThumbsup } from '~/components/icons/thumbs-up'
import { MotionButtonBase } from '~/components/ui/button'
import { useIsClient } from '~/hooks/common/use-is-client'
import { useCurrentPostData } from '~/hooks/data/use-post'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { toast } from '~/lib/toast'
import { urlBuilder } from '~/lib/url-builder'
import { getCurrentNoteData } from '~/providers/note/CurrentNodeDataProvider'
import { getCurrentNoteData } from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentNoteId } from '~/providers/note/CurrentNoteIdProvider'
import {
setCurrentPostData,
useCurrentPostDataSelector,
} from '~/providers/post/CurrentPostDataProvider'
import { useAggregationData } from '~/providers/root/aggregation-data-provider'
import { queries } from '~/queries/definition'
import { isLikedBefore, setLikeId } from '~/utils/cookie'
import { clsxm } from '~/utils/helper'
import { apiClient } from '~/utils/request'
Expand All @@ -38,25 +37,20 @@ export const PostActionAside: Component = ({ className }) => {
}

const LikeButton = () => {
const post = useCurrentPostData()

const queryClient = useQueryClient()
const control = useAnimationControls()
const [update] = useForceUpdate()
if (!post) return null
const id = post.id

const id = useCurrentPostDataSelector((data) => data?.id)
const nid = useCurrentNoteId()
if (!id) return null
const handleLike = () => {
if (isLikedBefore(id)) return
if (!nid) return
apiClient.note.likeIt(id).then(() => {
setLikeId(id)
queryClient.setQueriesData(
queries.post.bySlug(post.category.slug, post.slug),
(old: any) => {
return produce(old as NoteWrappedPayload, (draft) => {
draft.data.count.like += 1
})
},
)
setCurrentPostData((draft) => {
draft.count.like += 1
})
update()
})
}
Expand Down
32 changes: 19 additions & 13 deletions src/components/widgets/post/PostMetaBar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import type { PostModel } from '@mx-space/api-client'

import { MdiClockOutline } from '~/components/icons/clock'
import { FeHash } from '~/components/icons/fa-hash'
import { RelativeTime } from '~/components/ui/relative-time'
import { useCurrentPostDataSelector } from '~/providers/post/CurrentPostDataProvider'
import { clsxm } from '~/utils/helper'

export const PostMetaBar: Component<{ data: PostModel }> = ({
data,
className,
}) => {
export const PostMetaBar: Component = ({ className }) => {
const meta = useCurrentPostDataSelector((data) => {
if (!data) return
return {
created: data.created,
category: data.category,
tags: data.tags,
count: data.count,
}
})
if (!meta) return null
return (
<div
className={clsxm(
Expand All @@ -19,28 +25,28 @@ export const PostMetaBar: Component<{ data: PostModel }> = ({
<div className="flex min-w-0 items-center space-x-1">
<MdiClockOutline />
<span>
<RelativeTime date={data.created} />
<RelativeTime date={meta.created} />
</span>
</div>

<div className="flex min-w-0 items-center space-x-1">
<FeHash className="translate-y-[0.5px]" />
<span className="min-w-0 truncate">
{data.category.name}
{data.tags.length ? ` / ${data.tags.join(', ')}` : ''}
{meta.category.name}
{meta.tags.length ? ` / ${meta.tags.join(', ')}` : ''}
</span>
</div>

{!!data.count?.read && (
{!!meta.count?.read && (
<div className="flex min-w-0 items-center space-x-1">
<i className="icon-[mingcute--eye-2-line]" />
<span className="min-w-0 truncate">{data.count.read}</span>
<span className="min-w-0 truncate">{meta.count.read}</span>
</div>
)}
{!!data.count?.like && (
{!!meta.count?.like && (
<div className="flex min-w-0 items-center space-x-1">
<i className="icon-[mingcute--heart-fill]" />
<span className="min-w-0 truncate">{data.count.like}</span>
<span className="min-w-0 truncate">{meta.count.like}</span>
</div>
)}
</div>
Expand Down
10 changes: 3 additions & 7 deletions src/components/widgets/xlog/XLogInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ import type { XLogMeta } from './types'

import { Collapse } from '~/components/ui/collapse'
import { useIsClient } from '~/hooks/common/use-is-client'
import { useCurrentPostData } from '~/hooks/data/use-post'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNodeDataProvider'
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
import { useCurrentPostDataSelector } from '~/providers/post/CurrentPostDataProvider'

export const XLogInfoForPost: FC = () => {
const data = useCurrentPostData()

if (!data) return null

const meta = data.meta?.xLog
const meta = useCurrentPostDataSelector((data) => data?.meta?.xLog)
return <XLogInfoBase meta={meta} />
}

Expand Down
Loading

0 comments on commit bac61bb

Please sign in to comment.