@@ -8,17 +8,23 @@ import { useParams } from 'next/navigation'
8
8
import type { Image } from '@mx-space/api-client'
9
9
import type { MarkdownToJSX } from '~/components/ui/markdown'
10
10
11
+ import { ClientOnly } from '~/components/common/ClientOnly'
11
12
import { PageDataHolder } from '~/components/common/PageHolder'
13
+ import { MdiClockOutline } from '~/components/icons/clock'
12
14
import { useSetHeaderMetaInfo } from '~/components/layout/header/internal/hooks'
15
+ import { DividerVertical } from '~/components/ui/divider'
16
+ import { FloatPopover } from '~/components/ui/float-popover'
13
17
import { Loading } from '~/components/ui/loading'
14
18
import { Markdown } from '~/components/ui/markdown'
15
19
import { Toc , TocAutoScroll } from '~/components/widgets/toc'
16
20
import { useBeforeMounted } from '~/hooks/common/use-before-mounted'
17
- import { useNoteByNidQuery } from '~/hooks/data/use-note'
21
+ import { useNoteByNidQuery , useNoteData } from '~/hooks/data/use-note'
22
+ import { mood2icon , weather2icon } from '~/lib/meta-icon'
18
23
import { ArticleElementProvider } from '~/providers/article/article-element-provider'
19
24
import { MarkdownImageRecordProvider } from '~/providers/article/markdown-image-record-provider'
20
25
import { useSetCurrentNoteId } from '~/providers/note/current-note-id-provider'
21
26
import { NoteLayoutRightSidePortal } from '~/providers/note/right-side-provider'
27
+ import { parseDate } from '~/utils/datetime'
22
28
23
29
import styles from './page.module.css'
24
30
@@ -28,6 +34,10 @@ const PageImpl = () => {
28
34
const { id } = useParams ( ) as { id : string }
29
35
const { data } = useNoteByNidQuery ( id )
30
36
37
+ // Why do this, I mean why do set NoteId to context, don't use `useParams().id` for children components.
38
+ // Because any router params or query changes, will cause components that use `useParams()` hook, this hook is a context hook,
39
+ // For example, `ComA` use `useParams()` just want to get value `id`,
40
+ // but if router params or query changes `page` params, will cause `CompA` re - render.
31
41
const setNoteId = useSetCurrentNoteId ( )
32
42
useBeforeMounted ( ( ) => {
33
43
setNoteId ( id )
@@ -48,30 +58,26 @@ const PageImpl = () => {
48
58
return < Loading useDefaultLoadingText />
49
59
}
50
60
51
- // const mardownResult = parseMarkdown(note.text ?? '')
52
-
53
- // Why do this, I mean why do set NoteId to context, don't use `useParams().id` for children components.
54
- // Because any router params or query changes, will cause components that use `useParams()` hook, this hook is a context hook,
55
- // For example, `ComA` use `useParams()` just want to get value `id`,
56
- // but if router params or query changes `page` params, will cause `CompA` re - render.
57
-
58
- const dateFormat = dayjs ( data ?. data . created )
59
- . locale ( 'cn' )
60
- . format ( 'YYYY 年 M 月 D 日 dddd' )
61
+ const tips = `创建于 ${ parseDate ( note . created , 'YYYY 年 M 月 D 日 dddd' ) } ${
62
+ note . modified
63
+ ? `,修改于 ${ parseDate ( note . modified , 'YYYY 年 M 月 D 日 dddd' ) } `
64
+ : ''
65
+ } `
61
66
62
67
return (
63
68
< article
64
69
className = { clsx ( 'prose' , styles [ 'with-indent' ] , styles [ 'with-serif' ] ) }
65
70
>
66
71
< header >
67
- < h1 className = "mt-8 text-left font-bold text-base-content/95" >
68
- < Balancer > { note . title } </ Balancer >
69
- </ h1 >
70
-
72
+ < NoteTitle />
71
73
< span className = "inline-flex items-center text-[13px] text-neutral-content/60" >
72
- < time className = "font-medium" suppressHydrationWarning >
73
- { dateFormat }
74
- </ time >
74
+ < FloatPopover TriggerComponent = { NoteDateMeta } > { tips } </ FloatPopover >
75
+
76
+ < DividerVertical className = "!mx-2 scale-y-50" />
77
+
78
+ < ClientOnly >
79
+ < NoteMetaBar />
80
+ </ ClientOnly >
75
81
</ span >
76
82
</ header >
77
83
@@ -89,6 +95,59 @@ const PageImpl = () => {
89
95
)
90
96
}
91
97
98
+ const NoteTitle = ( ) => {
99
+ const note = useNoteData ( )
100
+ if ( ! note ) return null
101
+ const title = note . title
102
+ return (
103
+ < h1 className = "mt-8 text-left font-bold text-base-content/95" >
104
+ < Balancer > { title } </ Balancer >
105
+ </ h1 >
106
+ )
107
+ }
108
+
109
+ const NoteMetaBar = ( ) => {
110
+ const note = useNoteData ( )
111
+ if ( ! note ) return null
112
+
113
+ return (
114
+ < >
115
+ { note . weather && (
116
+ < span className = "inline-flex items-center space-x-1" >
117
+ { weather2icon ( note . weather ) }
118
+ < span className = "font-medium" > { note . weather } </ span >
119
+ < DividerVertical className = "!mx-2 scale-y-50" />
120
+ </ span >
121
+ ) }
122
+
123
+ { note . mood && (
124
+ < span className = "inline-flex items-center space-x-1" >
125
+ { mood2icon ( note . mood ) }
126
+ < span className = "font-medium" > { note . mood } </ span >
127
+ { /* <DividerVertical className="!mx-2 scale-y-50" /> */ }
128
+ </ span >
129
+ ) }
130
+ </ >
131
+ )
132
+ }
133
+ const NoteDateMeta = ( ) => {
134
+ const note = useNoteData ( )
135
+ if ( ! note ) return null
136
+
137
+ const dateFormat = dayjs ( note . created )
138
+ . locale ( 'zh-cn' )
139
+ . format ( 'YYYY 年 M 月 D 日 dddd' )
140
+
141
+ return (
142
+ < span className = "inline-flex items-center space-x-1" >
143
+ < MdiClockOutline />
144
+ < time className = "font-medium" suppressHydrationWarning >
145
+ { dateFormat }
146
+ </ time >
147
+ </ span >
148
+ )
149
+ }
150
+
92
151
const Markdownrenderers : { [ name : string ] : Partial < MarkdownToJSX . Rule > } = {
93
152
text : {
94
153
react ( node , _ , state ) {
@@ -100,6 +159,7 @@ const Markdownrenderers: { [name: string]: Partial<MarkdownToJSX.Rule> } = {
100
159
} ,
101
160
} ,
102
161
}
162
+
103
163
export default PageDataHolder ( PageImpl , ( ) => {
104
164
const { id } = useParams ( ) as { id : string }
105
165
return useNoteByNidQuery ( id )
0 commit comments