Skip to content

Commit

Permalink
feat: note meta icon
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jun 17, 2023
1 parent bc9f8ba commit f413e23
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 37 deletions.
6 changes: 6 additions & 0 deletions src/app/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import dayjs from "dayjs"
import 'dayjs/locale/zh-cn'

export const init = () => {
dayjs.locale('zh-cn')
}
7 changes: 5 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { dehydrate } from '@tanstack/react-query'
import { ClerkProvider } from '@clerk/nextjs'

import { Root } from '~/components/layout/root/Root'
import { ClerkZhCN } from '~/i18n/cherk-cn'
import { defineMetadata } from '~/lib/define-metadata'
import { sansFont, serifFont } from '~/lib/fonts'
import { getQueryClient } from '~/utils/query-client.server'

import { Providers } from '../providers/root'
import { Hydrate } from './hydrate'
import { init } from './init'

init()

export const generateMetadata = defineMetadata(async (_, getData) => {
const { seo, url, user } = await getData()
Expand Down Expand Up @@ -77,7 +79,8 @@ export default async function RootLayout(props: Props) {
})

return (
<ClerkProvider localization={ClerkZhCN}>
// <ClerkProvider localization={ClerkZhCN}>
<ClerkProvider>
<html lang="zh-CN" className="noise" suppressHydrationWarning>
<body
className={`${sansFont.variable} ${serifFont.variable} m-0 h-full p-0 font-sans antialiased`}
Expand Down
7 changes: 4 additions & 3 deletions src/app/notes/[id]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import RemoveMarkdown from 'remove-markdown'
import type { Metadata } from 'next'

import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
import { attachUA } from '~/lib/attach-ua'
import { getSummaryFromMd } from '~/lib/markdown'
import { queries } from '~/queries/definition'
import { getQueryClient } from '~/utils/query-client.server'

Expand All @@ -20,8 +20,9 @@ export const generateMetadata = async ({
const { data } = await getQueryClient().fetchQuery(
queries.note.byNid(params.id),
)
const { title, images } = data
const description = RemoveMarkdown(data.text).slice(0, 100)
const { title, images, text } = data
const description = getSummaryFromMd(text ?? '')

const ogImage = images?.length
? {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Expand Down
96 changes: 78 additions & 18 deletions src/app/notes/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@ import { useParams } from 'next/navigation'
import type { Image } from '@mx-space/api-client'
import type { MarkdownToJSX } from '~/components/ui/markdown'

import { ClientOnly } from '~/components/common/ClientOnly'
import { PageDataHolder } from '~/components/common/PageHolder'
import { MdiClockOutline } from '~/components/icons/clock'
import { useSetHeaderMetaInfo } from '~/components/layout/header/internal/hooks'
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 { Toc, TocAutoScroll } from '~/components/widgets/toc'
import { useBeforeMounted } from '~/hooks/common/use-before-mounted'
import { useNoteByNidQuery } from '~/hooks/data/use-note'
import { useNoteByNidQuery, useNoteData } from '~/hooks/data/use-note'
import { mood2icon, weather2icon } from '~/lib/meta-icon'
import { ArticleElementProvider } from '~/providers/article/article-element-provider'
import { MarkdownImageRecordProvider } from '~/providers/article/markdown-image-record-provider'
import { useSetCurrentNoteId } from '~/providers/note/current-note-id-provider'
import { NoteLayoutRightSidePortal } from '~/providers/note/right-side-provider'
import { parseDate } from '~/utils/datetime'

import styles from './page.module.css'

Expand All @@ -28,6 +34,10 @@ const PageImpl = () => {
const { id } = useParams() as { id: string }
const { data } = useNoteByNidQuery(id)

// Why do this, I mean why do set NoteId to context, don't use `useParams().id` for children components.
// Because any router params or query changes, will cause components that use `useParams()` hook, this hook is a context hook,
// For example, `ComA` use `useParams()` just want to get value `id`,
// but if router params or query changes `page` params, will cause `CompA` re - render.
const setNoteId = useSetCurrentNoteId()
useBeforeMounted(() => {
setNoteId(id)
Expand All @@ -48,30 +58,26 @@ const PageImpl = () => {
return <Loading useDefaultLoadingText />
}

// const mardownResult = parseMarkdown(note.text ?? '')

// Why do this, I mean why do set NoteId to context, don't use `useParams().id` for children components.
// Because any router params or query changes, will cause components that use `useParams()` hook, this hook is a context hook,
// For example, `ComA` use `useParams()` just want to get value `id`,
// but if router params or query changes `page` params, will cause `CompA` re - render.

const dateFormat = dayjs(data?.data.created)
.locale('cn')
.format('YYYY 年 M 月 D 日 dddd')
const tips = `创建于 ${parseDate(note.created, 'YYYY 年 M 月 D 日 dddd')}${
note.modified
? `,修改于 ${parseDate(note.modified, 'YYYY 年 M 月 D 日 dddd')}`
: ''
}`

return (
<article
className={clsx('prose', styles['with-indent'], styles['with-serif'])}
>
<header>
<h1 className="mt-8 text-left font-bold text-base-content/95">
<Balancer>{note.title}</Balancer>
</h1>

<NoteTitle />
<span className="inline-flex items-center text-[13px] text-neutral-content/60">
<time className="font-medium" suppressHydrationWarning>
{dateFormat}
</time>
<FloatPopover TriggerComponent={NoteDateMeta}>{tips}</FloatPopover>

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

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

Expand All @@ -89,6 +95,59 @@ const PageImpl = () => {
)
}

const NoteTitle = () => {
const note = useNoteData()
if (!note) return null
const title = note.title
return (
<h1 className="mt-8 text-left font-bold text-base-content/95">
<Balancer>{title}</Balancer>
</h1>
)
}

const NoteMetaBar = () => {
const note = useNoteData()
if (!note) return null

return (
<>
{note.weather && (
<span className="inline-flex items-center space-x-1">
{weather2icon(note.weather)}
<span className="font-medium">{note.weather}</span>
<DividerVertical className="!mx-2 scale-y-50" />
</span>
)}

{note.mood && (
<span className="inline-flex items-center space-x-1">
{mood2icon(note.mood)}
<span className="font-medium">{note.mood}</span>
{/* <DividerVertical className="!mx-2 scale-y-50" /> */}
</span>
)}
</>
)
}
const NoteDateMeta = () => {
const note = useNoteData()
if (!note) return null

const dateFormat = dayjs(note.created)
.locale('zh-cn')
.format('YYYY 年 M 月 D 日 dddd')

return (
<span className="inline-flex items-center space-x-1">
<MdiClockOutline />
<time className="font-medium" suppressHydrationWarning>
{dateFormat}
</time>
</span>
)
}

const Markdownrenderers: { [name: string]: Partial<MarkdownToJSX.Rule> } = {
text: {
react(node, _, state) {
Expand All @@ -100,6 +159,7 @@ const Markdownrenderers: { [name: string]: Partial<MarkdownToJSX.Rule> } = {
},
},
}

export default PageDataHolder(PageImpl, () => {
const { id } = useParams() as { id: string }
return useNoteByNidQuery(id)
Expand Down
7 changes: 7 additions & 0 deletions src/components/common/ClientOnly.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useIsClient } from '~/hooks/common/use-is-client'

export const ClientOnly: Component = (props) => {
const isClient = useIsClient()
if (!isClient) return null
return <>{props.children}</>
}
4 changes: 2 additions & 2 deletions src/components/layout/header/internal/BluredBackground.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use client'

import clsx from 'clsx'

import { useHeaderBgOpacity } from './hooks'
import clsx from 'clsx'

export const BluredBackground = () => {
const headerOpacity = useHeaderBgOpacity()
return (
<div
className={clsx(
'absolute inset-0 transform-gpu [backdrop-filter:saturate(180%)_blur(20px)] [backface-visibility:hidden]',
'absolute inset-0 transform-gpu [-webkit-backdrop-filter:saturate(180%)_blur(20px)] [backdrop-filter:saturate(180%)_blur(20px)] [backface-visibility:hidden]',
'bg-themed-bg_opacity [border-bottom:1px_solid_rgb(187_187_187_/_20%)]',
)}
style={{
Expand Down
9 changes: 5 additions & 4 deletions src/components/ui/divider/Divider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react'
import { clsx } from 'clsx'
import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react'

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

export const Divider: FC<
DetailedHTMLProps<HTMLAttributes<HTMLHRElement>, HTMLHRElement>
> = (props) => {
const { className, ...rest } = props
return (
<hr
className={clsx(
className={clsxm(
'my-4 h-[0.5px] border-0 bg-always-black !bg-opacity-30 dark:bg-always-white',
className,
)}
Expand All @@ -23,8 +24,8 @@ export const DividerVertical: FC<
const { className, ...rest } = props
return (
<span
className={clsx(
'mx-4 inline-block h-full w-[0.5px] bg-always-black !bg-opacity-30 text-transparent dark:bg-always-white',
className={clsxm(
'mx-4 inline-block h-full w-[0.5px] select-none bg-always-black !bg-opacity-30 text-transparent dark:bg-always-white',
className,
)}
{...rest}
Expand Down
3 changes: 1 addition & 2 deletions src/components/ui/float-popover/FloatPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { flip, offset, shift, useFloating } from '@floating-ui/react-dom'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import clsx from 'clsx'
import type { UseFloatingOptions } from '@floating-ui/react-dom'
import type { FC, PropsWithChildren } from 'react'

Expand Down Expand Up @@ -192,7 +191,7 @@ export const FloatPopover: FC<
<As
// @ts-ignore
role={trigger === 'both' || trigger === 'click' ? 'button' : 'note'}
className={clsx('inline-block', wrapperClassNames)}
className={clsxm('inline-block', wrapperClassNames)}
ref={refs.setReference}
{...listener}
>
Expand Down
Loading

0 comments on commit f413e23

Please sign in to comment.