Skip to content

Commit

Permalink
feat: support xlog component
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jun 18, 2023
1 parent 96fe3fa commit 6a0c2b9
Show file tree
Hide file tree
Showing 39 changed files with 1,061 additions and 587 deletions.
21 changes: 21 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,24 @@ declare global {
}

export {}

declare module '@mx-space/api-client' {
export interface PostMeta {
style?: string
cover?: string
banner?: string | { type: string; message: string }
}
interface TextBaseModel extends BaseCommentIndexModel {
meta?: PostMeta
}

interface AggregateTopNote {
meta?: PostMeta
}

interface AggregateTopPost {
meta?: PostMeta
}
}

export {}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"markdown-escape": "2.0.0",
"markdown-to-jsx": "npm:@innei/markdown-to-jsx@7.1.3-beta.2",
"mdast-util-toc": "6.1.1",
"medium-zoom": "1.0.8",
"next": "13.4.6",
"next-themes": "0.2.1",
"react": "18.2.0",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 1 addition & 7 deletions src/app/error.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
'use client'

export default ({ error, reset }: any) => {
return (
<html>
<body>
<div>Something went wrong</div>
</body>
</html>
)
return <div>Something went wrong</div>
}
76 changes: 49 additions & 27 deletions src/app/notes/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import { DividerVertical } from '~/components/ui/divider'
import { FloatPopover } from '~/components/ui/float-popover'
import { Loading } from '~/components/ui/loading'
import { Markdown } from '~/components/ui/markdown'
import { NoteTopic } from '~/components/widgets/note/NoteTopic'
import { Toc, TocAutoScroll } from '~/components/widgets/toc'
import { XLogInfoForNote, XLogSummaryForNote } from '~/components/widgets/xlog'
import { useBeforeMounted } from '~/hooks/common/use-before-mounted'
import { useNoteByNidQuery, useNoteData } from '~/hooks/data/use-note'
import { mood2icon, weather2icon } from '~/lib/meta-icon'
Expand Down Expand Up @@ -67,31 +69,41 @@ const PageImpl = () => {
}`

return (
<article
className={clsx('prose', styles['with-indent'], styles['with-serif'])}
>
<header>
<NoteTitle />
<span className="inline-flex items-center text-[13px] text-neutral-content/60">
<FloatPopover TriggerComponent={NoteDateMeta}>{tips}</FloatPopover>

<ClientOnly>
<NoteMetaBar />
</ClientOnly>
</span>
</header>

<ArticleElementProvider>
<MarkdownImageRecordProvider images={note.images || noopArr}>
<Markdown as="main" renderers={Markdownrenderers} value={note.text} />
</MarkdownImageRecordProvider>

<NoteLayoutRightSidePortal>
<Toc className="sticky top-[120px] ml-4 mt-[120px]" />
<TocAutoScroll />
</NoteLayoutRightSidePortal>
</ArticleElementProvider>
</article>
<>
<article
className={clsx('prose', styles['with-indent'], styles['with-serif'])}
>
<header>
<NoteTitle />
<span className="inline-flex items-center text-[13px] text-neutral-content/60">
<FloatPopover TriggerComponent={NoteDateMeta}>{tips}</FloatPopover>

<ClientOnly>
<NoteMetaBar />
</ClientOnly>
</span>
</header>

<XLogSummaryForNote />

<ArticleElementProvider>
<MarkdownImageRecordProvider images={note.images || noopArr}>
<Markdown
as="main"
renderers={MarkdownRenderers}
value={note.text}
/>
</MarkdownImageRecordProvider>

<NoteLayoutRightSidePortal>
<Toc className="sticky top-[120px] ml-4 mt-[120px]" />
<TocAutoScroll />
</NoteLayoutRightSidePortal>
</ArticleElementProvider>
</article>
{!!note.topic && <NoteTopic topic={note.topic} />}
<XLogInfoForNote />
</>
)
}

Expand All @@ -111,7 +123,7 @@ const NoteMetaBar = () => {
if (!note) return null

const children = [] as ReactNode[]
if (note.weather || !note.mood) {
if (note.weather || note.mood) {
children.push(<DividerVertical className="!mx-2 scale-y-50" key="d0" />)
}

Expand Down Expand Up @@ -144,6 +156,16 @@ const NoteMetaBar = () => {
)
}

if (note.count.like > 0) {
children.push(
<DividerVertical className="!mx-2 scale-y-50" key="d2" />,
<span className="inline-flex items-center space-x-1" key="linkcount">
<i className="icon-[mingcute--heart-line]" />
<span className="font-medium">{note.count.like}</span>
</span>,
)
}

return children
}

Expand All @@ -165,7 +187,7 @@ const NoteDateMeta = () => {
)
}

const Markdownrenderers: { [name: string]: Partial<MarkdownToJSX.Rule> } = {
const MarkdownRenderers: { [name: string]: Partial<MarkdownToJSX.Rule> } = {
text: {
react(node, _, state) {
return (
Expand Down
2 changes: 1 addition & 1 deletion src/app/notes/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async (props: PropsWithChildren) => {
className={clsx(
'relative mx-auto grid min-h-screen max-w-[60rem]',
'gap-4 md:grid-cols-1 lg:max-w-[calc(60rem+400px)] lg:grid-cols-[1fr_minmax(auto,60rem)_1fr]',
'mt-24',
'mt-12 md:mt-24',
)}
>
<NoteLeftSidebar className="relative hidden lg:block" />
Expand Down
47 changes: 47 additions & 0 deletions src/components/common/AutoResizeHeight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useEffect, useRef, useState } from 'react'
import { motion } from 'framer-motion'

import { clsxm } from '~/utils/helper'

interface AnimateChangeInHeightProps {
children: React.ReactNode
className?: string
duration?: number
}

export const AutoResizeHeight: React.FC<AnimateChangeInHeightProps> = ({
children,
className,
duration = 0.6,
}) => {
const containerRef = useRef<HTMLDivElement | null>(null)
const [height, setHeight] = useState<number | 'auto'>('auto')

useEffect(() => {
if (containerRef.current) {
const resizeObserver = new ResizeObserver((entries) => {
// We only have one entry, so we can use entries[0].
const observedHeight = entries[0].contentRect.height
setHeight(observedHeight)
})

resizeObserver.observe(containerRef.current)

return () => {
// Cleanup the observer when the component is unmounted
resizeObserver.disconnect()
}
}
}, [])

return (
<motion.div
className={clsxm('overflow-hidden', className)}
style={{ height }}
animate={{ height }}
transition={{ duration }}
>
<div ref={containerRef}>{children}</div>
</motion.div>
)
}
11 changes: 9 additions & 2 deletions src/components/common/Lazyload.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useEffect } from 'react'
import { useInView } from 'react-intersection-observer'
import type { FC, PropsWithChildren } from 'react'
import type { IntersectionOptions } from 'react-intersection-observer'
Expand All @@ -14,9 +14,16 @@ export const LazyLoad: FC<PropsWithChildren & LazyLoadProps> = (props) => {
rootMargin: `${offset || 0}px`,
...rest,
})
const [isLoaded, setIsLoaded] = React.useState(false)
useEffect(() => {
if (inView) {
setIsLoaded(true)
}
}, [inView])

return (
<>
<span data-testid="lazyload-indicator" ref={ref} />
{!isLoaded && <span data-testid="lazyload-indicator" ref={ref} />}
{!inView ? placeholder : props.children}
</>
)
Expand Down
1 change: 1 addition & 0 deletions src/components/layout/header/internal/AnimatedLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const AnimatedLogo = () => {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="scale-75"
>
<Logo />
</motion.div>
Expand Down
14 changes: 9 additions & 5 deletions src/components/layout/header/internal/HeaderActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
export const HeaderActionButton: Component<JSX.IntrinsicElements['button']> = ({
children,
...rest
}) => {
import { forwardRef } from 'react'
import type { ForwardRefComponent } from 'framer-motion'

export const HeaderActionButton: ForwardRefComponent<
HTMLButtonElement,
JSX.IntrinsicElements['button']
> = forwardRef(({ children, ...rest }, ref) => {
return (
<button
className="group h-10 rounded-full bg-gradient-to-b from-zinc-50/50 to-white/90 px-3 text-sm shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur transition dark:from-zinc-900/50 dark:to-zinc-800/90 dark:ring-white/10 dark:hover:ring-white/20"
{...rest}
ref={ref}
>
{children}
</button>
)
}
})
87 changes: 47 additions & 40 deletions src/components/layout/header/internal/HeaderDrawerButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import Link from 'next/link'
import type { SVGProps } from 'react'

import { CloseIcon } from '~/components/icons/close'
import { MotionButtonBase } from '~/components/ui/button/MotionButton'
import { MotionButtonBase } from '~/components/ui/button'
import { reboundPreset } from '~/constants/spring'
import { useIsClient } from '~/hooks/common/use-is-client'
import { jotaiStore } from '~/lib/store'

import { HeaderActionButton } from './HeaderActionButton'
Expand All @@ -30,50 +31,56 @@ const drawerOpenAtom = atom(false)
export const HeaderDrawerButton = () => {
const [open, setOpen] = useAtom(drawerOpenAtom)

const isClient = useIsClient()
const ButtonElement = (
<HeaderActionButton>
<IcBaselineMenuOpen />
</HeaderActionButton>
)
if (!isClient) return ButtonElement

return (
<Dialog.Root open={open} onOpenChange={(open) => setOpen(open)}>
<Dialog.Trigger asChild>
<HeaderActionButton>
<IcBaselineMenuOpen />
</HeaderActionButton>
</Dialog.Trigger>
<Dialog.Trigger asChild>{ButtonElement}</Dialog.Trigger>
<Dialog.Portal forceMount>
<AnimatePresence>
{open && (
<>
<Dialog.Overlay asChild>
<motion.div
className="fixed inset-0 z-[11] bg-slate-50/80 backdrop-blur-sm dark:bg-slate-900/80"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
</Dialog.Overlay>
<div>
<AnimatePresence>
{open && (
<>
<Dialog.Overlay asChild>
<motion.div
className="fixed inset-0 z-[11] bg-slate-50/80 backdrop-blur-sm dark:bg-slate-900/80"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
</Dialog.Overlay>

<Dialog.Content>
<motion.dialog
className="fixed inset-0 z-[12] flex max-h-[100vh] min-h-0 items-center justify-center overflow-hidden rounded-xl bg-base-100/90"
initial={{ opacity: 0.8 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Dialog.DialogClose asChild>
<MotionButtonBase
className="absolute right-4 top-4 p-4"
onClick={() => {
setOpen(false)
}}
>
<CloseIcon />
</MotionButtonBase>
</Dialog.DialogClose>
<Dialog.Content>
<motion.dialog
className="fixed inset-0 z-[12] flex max-h-[100vh] min-h-0 items-center justify-center overflow-hidden rounded-xl bg-base-100/90"
initial={{ opacity: 0.8 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Dialog.DialogClose asChild>
<MotionButtonBase
className="absolute right-4 top-4 p-4"
onClick={() => {
setOpen(false)
}}
>
<CloseIcon />
</MotionButtonBase>
</Dialog.DialogClose>

<HeaderDrawerContent />
</motion.dialog>
</Dialog.Content>
</>
)}
</AnimatePresence>
<HeaderDrawerContent />
</motion.dialog>
</Dialog.Content>
</>
)}
</AnimatePresence>
</div>
</Dialog.Portal>
</Dialog.Root>
)
Expand Down
Loading

0 comments on commit 6a0c2b9

Please sign in to comment.