Skip to content

Commit 571c049

Browse files
committed
feat: note left bar dont sticky when scroll out paper
Signed-off-by: Innei <[email protected]>
1 parent 2393a99 commit 571c049

File tree

9 files changed

+94
-30
lines changed

9 files changed

+94
-30
lines changed

src/app/notes/Paper.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { clsxm } from '~/utils/helper'
22

3-
export const Paper: Component = ({ children, className }) => {
3+
export const Paper: Component<{
4+
as?: keyof JSX.IntrinsicElements | Component
5+
}> = ({ children, className, as: As = 'main' }) => {
46
return (
5-
<main
7+
<As
68
className={clsxm(
79
'relative bg-slate-50 dark:bg-zinc-900 md:col-start-1 lg:col-auto',
810
'-m-4 p-[2rem_1rem] md:m-0 lg:p-[30px_45px]',
@@ -12,6 +14,6 @@ export const Paper: Component = ({ children, className }) => {
1214
)}
1315
>
1416
{children}
15-
</main>
17+
</As>
1618
)
1719
}

src/app/notes/[id]/layout.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { headers } from 'next/dist/client/components/headers'
22
import type { Metadata } from 'next'
33

44
import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
5+
import { Comments } from '~/components/widgets/comment/Comments'
6+
import { NoteMainContainer } from '~/components/widgets/note/NoteMainContainer'
57
import { REQUEST_QUERY } from '~/constants/system'
68
import { attachUA } from '~/lib/attach-ua'
79
import { getSummaryFromMd } from '~/lib/markdown'
@@ -78,7 +80,8 @@ export default async (
7880
<SyncNoteDataAfterLoggedIn />
7981

8082
<BottomToUpTransitionView className="min-w-0">
81-
<Paper>{props.children}</Paper>
83+
<Paper as={NoteMainContainer}>{props.children}</Paper>
84+
<Comments refId={id} />
8285
</BottomToUpTransitionView>
8386
</>
8487
)

src/components/ui/theme-switcher/ThemeSwitcher.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ const ThemeIndicator = () => {
112112
if (!theme) return null
113113
return (
114114
<div
115-
className="absolute top-[4px] z-[-1] h-[32px] w-[32px] rounded-full bg-base-100 shadow-[0_1px_2px_0_rgba(122,122,122,.2),_0_1px_3px_0_rgba(122,122,122,.1)] duration-200"
115+
className="absolute top-[4px] z-[-1] h-[32px] w-[32px] rounded-full bg-base-100 shadow-[0_1px_2px_0_rgba(127.5,127.5,127.5,.2),_0_1px_3px_0_rgba(127.5,127.5,127.5,.1)] duration-200"
116116
style={{
117117
left: { light: 4, system: 36, dark: 68 }[theme],
118118
}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { FC } from 'react'
2+
3+
export const Comments: FC<{
4+
refId: string
5+
}> = ({ refId }) => {
6+
return (
7+
<div className="relative mb-[60px] mt-[120px] min-h-[10000px]">
8+
Comments WIP, RefId: {refId}
9+
</div>
10+
)
11+
}

src/components/widgets/note/NoteActionAside.tsx

+11-14
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,10 @@ const LikeButton = () => {
106106
}
107107

108108
const ShareButton = () => {
109-
const hasShare = 'share' in navigator
110109
const isClient = useIsClient()
111110

112111
if (!isClient) return null
113112

114-
if (!hasShare) {
115-
return null
116-
}
117-
118113
return (
119114
<MotionButtonBase
120115
aria-label="Share This Note Button"
@@ -124,15 +119,17 @@ const ShareButton = () => {
124119

125120
if (!note) return
126121

127-
navigator.share({
128-
title: note.title,
129-
text: note.text,
130-
url: urlBuilder(
131-
routeBuilder(Routes.Note, {
132-
id: note.nid.toString(),
133-
}),
134-
).href,
135-
})
122+
const hasShare = 'share' in navigator
123+
if (hasShare)
124+
navigator.share({
125+
title: note.title,
126+
text: note.text,
127+
url: urlBuilder(
128+
routeBuilder(Routes.Note, {
129+
id: note.nid.toString(),
130+
}),
131+
).href,
132+
})
136133
}}
137134
>
138135
<i className="icon-[mingcute--share-forward-fill] text-[24px] opacity-80 duration-200 hover:text-uk-cyan-light hover:opacity-100" />
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1+
'use client'
2+
13
import { OnlyDesktop } from '~/components/ui/viewport'
24

5+
import { useNoteMainContainerHeight } from './NoteMainContainer'
36
import { NoteTimeline } from './NoteTimeline'
47
import { NoteTopicInfo } from './NoteTopicInfo'
58

69
export const NoteLeftSidebar: Component = ({ className }) => {
710
return (
8-
<div className={className}>
11+
<AutoHeightOptimize className={className}>
912
<OnlyDesktop>
10-
<div className="sticky top-[120px] mt-[120px]">
13+
<div className="sticky top-[120px] mt-[120px] min-h-[300px]">
1114
<NoteTimeline />
1215

1316
<NoteTopicInfo />
1417
</div>
1518
</OnlyDesktop>
19+
</AutoHeightOptimize>
20+
)
21+
}
22+
23+
const AutoHeightOptimize: Component = ({ children }) => {
24+
const mainContainerHeight = useNoteMainContainerHeight()
25+
return (
26+
<div
27+
style={{
28+
height: mainContainerHeight ? `${mainContainerHeight}px` : 'auto',
29+
}}
30+
>
31+
{children}
1632
</div>
1733
)
1834
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use client'
2+
3+
import { useEffect, useRef } from 'react'
4+
import { atom, useAtomValue, useSetAtom } from 'jotai'
5+
6+
import { jotaiStore } from '~/lib/store'
7+
8+
const noteMainContainerHeightAtom = atom(0)
9+
export const NoteMainContainer: Component = ({ className, children }) => {
10+
const mainRef = useRef<HTMLDivElement>(null)
11+
const setHeight = useSetAtom(noteMainContainerHeightAtom)
12+
useEffect(() => {
13+
if (!mainRef.current) return
14+
// measure the height of the main element
15+
const mainHeight = mainRef.current.offsetHeight
16+
if (mainHeight) setHeight(mainHeight)
17+
18+
const ob = new ResizeObserver((entries) => {
19+
const mainHeight = (entries[0].target as HTMLElement).offsetHeight
20+
if (mainHeight) setHeight(mainHeight)
21+
})
22+
ob.observe(mainRef.current)
23+
24+
return () => {
25+
ob.disconnect()
26+
jotaiStore.set(noteMainContainerHeightAtom, 0)
27+
}
28+
}, [])
29+
30+
return (
31+
<main className={className} ref={mainRef}>
32+
{children}
33+
</main>
34+
)
35+
}
36+
37+
export const useNoteMainContainerHeight = () =>
38+
useAtomValue(noteMainContainerHeightAtom)

src/components/widgets/note/NoteTimeline.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import { clsxm } from '~/utils/helper'
1414
import { apiClient } from '~/utils/request'
1515
import { springScrollToTop } from '~/utils/scroller'
1616

17-
export const NoteTimeline = () => {
17+
export const NoteTimeline = memo(() => {
1818
const noteId = useCurrentNoteId()
1919
if (!noteId) return null
2020
return <NoteTimelineImpl />
21-
}
21+
})
2222

2323
const NoteTimelineImpl = () => {
2424
void useCurrentNoteId()

src/components/widgets/note/NoteTopicInfo.tsx

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

3+
import { memo } from 'react'
4+
35
import { Divider } from '~/components/ui/divider'
46
import { FloatPopover } from '~/components/ui/float-popover'
57
import { useCurrentNoteDataSelector } from '~/providers/note/CurrentNoteDataProvider'
68

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

9-
// export const NoteTopicInfo = () => {
10-
// const noteId = useCurrentNoteId()
11-
// if (!noteId) return null
12-
// return <NoteTopicInfoImpl />
13-
// }
14-
export const NoteTopicInfo = () => {
11+
export const NoteTopicInfo = memo(() => {
1512
const topic = useCurrentNoteDataSelector((data) => data?.data.topic)
1613

1714
if (!topic) return null
@@ -33,4 +30,4 @@ export const NoteTopicInfo = () => {
3330
</FloatPopover>
3431
</>
3532
)
36-
}
33+
})

0 commit comments

Comments
 (0)