Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
c0d62241
Commit
c0d62241
authored
Jan 22, 2026
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: enable compact mode for list view
parent
6c9ea31d
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
33 additions
and
28 deletions
+33
-28
MasonryView.tsx
web/src/components/MasonryView/MasonryView.tsx
+2
-2
constants.ts
web/src/components/MemoContent/constants.ts
+7
-1
hooks.ts
web/src/components/MemoContent/hooks.ts
+3
-2
index.tsx
web/src/components/MemoContent/index.tsx
+16
-8
Archived.tsx
web/src/pages/Archived.tsx
+1
-4
Explore.tsx
web/src/pages/Explore.tsx
+1
-4
Home.tsx
web/src/pages/Home.tsx
+1
-4
UserProfile.tsx
web/src/pages/UserProfile.tsx
+2
-3
No files found.
web/src/components/MasonryView/MasonryView.tsx
View file @
c0d62241
...
...
@@ -10,10 +10,10 @@ const MasonryView = ({ memoList, renderer, prefixElement, listMode = false }: Ma
const
{
columns
,
distribution
,
handleHeightChange
}
=
useMasonryLayout
(
memoList
,
listMode
,
containerRef
,
prefixElementRef
);
// Create render context: a
utomatically enable compact mode when multiple column
s
// Create render context: a
lways enable compact mode for list view
s
const
renderContext
:
MemoRenderContext
=
useMemo
(
()
=>
({
compact
:
columns
>
1
,
compact
:
true
,
columns
,
}),
[
columns
],
...
...
web/src/components/MemoContent/constants.ts
View file @
c0d62241
import
{
defaultSchema
}
from
"rehype-sanitize"
;
export
const
MAX_DISPLAY_HEIGHT
=
256
;
// Compact mode display settings
export
const
COMPACT_MODE_CONFIG
=
{
maxHeightVh
:
60
,
// 60% of viewport height
gradientHeight
:
"h-24"
,
// Tailwind class for gradient overlay
}
as
const
;
export
const
getMaxDisplayHeight
=
()
=>
window
.
innerHeight
*
(
COMPACT_MODE_CONFIG
.
maxHeightVh
/
100
);
export
const
COMPACT_STATES
:
Record
<
"ALL"
|
"SNIPPET"
,
{
textKey
:
string
;
next
:
"ALL"
|
"SNIPPET"
}
>
=
{
ALL
:
{
textKey
:
"memo.show-more"
,
next
:
"SNIPPET"
},
...
...
web/src/components/MemoContent/hooks.ts
View file @
c0d62241
import
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
COMPACT_STATES
,
MAX_DISPLAY_HEIGHT
}
from
"./constants"
;
import
{
COMPACT_STATES
,
getMaxDisplayHeight
}
from
"./constants"
;
import
type
{
ContentCompactView
}
from
"./types"
;
export
const
useCompactMode
=
(
enabled
:
boolean
)
=>
{
...
...
@@ -8,7 +8,8 @@ export const useCompactMode = (enabled: boolean) => {
useEffect
(()
=>
{
if
(
!
enabled
||
!
containerRef
.
current
)
return
;
if
(
containerRef
.
current
.
getBoundingClientRect
().
height
>
MAX_DISPLAY_HEIGHT
)
{
const
maxHeight
=
getMaxDisplayHeight
();
if
(
containerRef
.
current
.
getBoundingClientRect
().
height
>
maxHeight
)
{
setMode
(
"ALL"
);
}
},
[
enabled
]);
...
...
web/src/components/MemoContent/index.tsx
View file @
c0d62241
import
type
{
Element
}
from
"hast"
;
import
{
ChevronDown
,
ChevronUp
}
from
"lucide-react"
;
import
{
memo
}
from
"react"
;
import
ReactMarkdown
from
"react-markdown"
;
import
rehypeKatex
from
"rehype-katex"
;
...
...
@@ -14,7 +15,7 @@ import { remarkPreserveType } from "@/utils/remark-plugins/remark-preserve-type"
import
{
remarkTag
}
from
"@/utils/remark-plugins/remark-tag"
;
import
{
CodeBlock
}
from
"./CodeBlock"
;
import
{
isTagNode
,
isTaskListItemNode
}
from
"./ConditionalComponent"
;
import
{
SANITIZE_SCHEMA
}
from
"./constants"
;
import
{
COMPACT_MODE_CONFIG
,
SANITIZE_SCHEMA
}
from
"./constants"
;
import
{
useCompactLabel
,
useCompactMode
}
from
"./hooks"
;
import
{
Tag
}
from
"./Tag"
;
import
{
TaskListItem
}
from
"./TaskListItem"
;
...
...
@@ -37,7 +38,7 @@ const MemoContent = (props: MemoContentProps) => {
ref=
{
memoContentContainerRef
}
className=
{
cn
(
"markdown-content relative w-full max-w-full wrap-break-word text-base leading-6"
,
showCompactMode
===
"ALL"
&&
"line-clamp-6 max-h-60"
,
showCompactMode
===
"ALL"
&&
`max-h-[${COMPACT_MODE_CONFIG.maxHeightVh}vh] overflow-hidden`
,
contentClassName
,
)
}
onMouseUp=
{
onClick
}
...
...
@@ -71,18 +72,25 @@ const MemoContent = (props: MemoContentProps) => {
>
{
content
}
</
ReactMarkdown
>
{
showCompactMode
===
"ALL"
&&
(
<
div
className=
{
cn
(
"absolute inset-x-0 bottom-0 pointer-events-none"
,
COMPACT_MODE_CONFIG
.
gradientHeight
,
"bg-linear-to-t from-background from-0% via-background/60 via-40% to-transparent to-100%"
,
)
}
/>
)
}
</
div
>
{
showCompactMode
===
"ALL"
&&
(
<
div
className=
"absolute bottom-0 left-0 w-full h-12 bg-linear-to-b from-transparent to-background pointer-events-none"
></
div
>
)
}
{
showCompactMode
!==
undefined
&&
(
<
div
className=
"
w-full mt-1
"
>
<
div
className=
"
relative w-full mt-2
"
>
<
button
type=
"button"
className=
"
w-auto flex flex-row justify-start items-center cursor-pointer text-sm text-primary hover:opacity-80 text-left
"
className=
"
group inline-flex items-center gap-1 px-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors
"
onClick=
{
toggleCompactMode
}
>
{
compactLabel
}
<
span
>
{
compactLabel
}
</
span
>
{
showCompactMode
===
"ALL"
?
<
ChevronDown
className=
"w-3 h-3"
/>
:
<
ChevronUp
className=
"w-3 h-3"
/>
}
</
button
>
</
div
>
)
}
...
...
web/src/pages/Archived.tsx
View file @
c0d62241
import
{
MemoRenderContext
}
from
"@/components/MasonryView"
;
import
MemoView
from
"@/components/MemoView"
;
import
PagedMemoList
from
"@/components/PagedMemoList"
;
import
{
useMemoFilters
,
useMemoSorting
}
from
"@/hooks"
;
...
...
@@ -24,9 +23,7 @@ const Archived = () => {
return
(
<
PagedMemoList
renderer=
{
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
(
<
MemoView
key=
{
`${memo.name}-${memo.updateTime}`
}
memo=
{
memo
}
showVisibility
compact=
{
context
?.
compact
}
/>
)
}
renderer=
{
(
memo
:
Memo
)
=>
<
MemoView
key=
{
`${memo.name}-${memo.updateTime}`
}
memo=
{
memo
}
showVisibility
compact
/>
}
listSort=
{
listSort
}
state=
{
State
.
ARCHIVED
}
orderBy=
{
orderBy
}
...
...
web/src/pages/Explore.tsx
View file @
c0d62241
import
{
MemoRenderContext
}
from
"@/components/MasonryView"
;
import
MemoView
from
"@/components/MemoView"
;
import
PagedMemoList
from
"@/components/PagedMemoList"
;
import
{
useMemoFilters
,
useMemoSorting
}
from
"@/hooks"
;
...
...
@@ -30,9 +29,7 @@ const Explore = () => {
return
(
<
PagedMemoList
renderer=
{
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
(
<
MemoView
key=
{
`${memo.name}-${memo.updateTime}`
}
memo=
{
memo
}
showCreator
showVisibility
compact=
{
context
?.
compact
}
/>
)
}
renderer=
{
(
memo
:
Memo
)
=>
<
MemoView
key=
{
`${memo.name}-${memo.updateTime}`
}
memo=
{
memo
}
showCreator
showVisibility
compact
/>
}
listSort=
{
listSort
}
orderBy=
{
orderBy
}
filter=
{
memoFilter
}
...
...
web/src/pages/Home.tsx
View file @
c0d62241
import
{
MemoRenderContext
}
from
"@/components/MasonryView"
;
import
MemoView
from
"@/components/MemoView"
;
import
PagedMemoList
from
"@/components/PagedMemoList"
;
import
{
useInstance
}
from
"@/contexts/InstanceContext"
;
...
...
@@ -25,9 +24,7 @@ const Home = () => {
return
(
<
div
className=
"w-full min-h-full bg-background text-foreground"
>
<
PagedMemoList
renderer=
{
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
(
<
MemoView
key=
{
`${memo.name}-${memo.displayTime}`
}
memo=
{
memo
}
showVisibility
showPinned
compact=
{
context
?.
compact
}
/>
)
}
renderer=
{
(
memo
:
Memo
)
=>
<
MemoView
key=
{
`${memo.name}-${memo.displayTime}`
}
memo=
{
memo
}
showVisibility
showPinned
compact
/>
}
listSort=
{
listSort
}
orderBy=
{
orderBy
}
filter=
{
memoFilter
}
...
...
web/src/pages/UserProfile.tsx
View file @
c0d62241
...
...
@@ -2,7 +2,6 @@ import copy from "copy-to-clipboard";
import
{
ExternalLinkIcon
,
LayoutListIcon
,
type
LucideIcon
,
MapIcon
}
from
"lucide-react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useParams
,
useSearchParams
}
from
"react-router-dom"
;
import
{
MemoRenderContext
}
from
"@/components/MasonryView"
;
import
MemoView
from
"@/components/MemoView"
;
import
PagedMemoList
from
"@/components/PagedMemoList"
;
import
UserAvatar
from
"@/components/UserAvatar"
;
...
...
@@ -130,8 +129,8 @@ const UserProfile = () => {
<
div
className=
"mx-auto w-full max-w-2xl"
>
{
activeTab
===
"memos"
?
(
<
PagedMemoList
renderer=
{
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
(
<
MemoView
key=
{
`${memo.name}-${memo.displayTime}`
}
memo=
{
memo
}
showVisibility
showPinned
compact
=
{
context
?.
compact
}
/>
renderer=
{
(
memo
:
Memo
)
=>
(
<
MemoView
key=
{
`${memo.name}-${memo.displayTime}`
}
memo=
{
memo
}
showVisibility
showPinned
compact
/>
)
}
listSort=
{
listSort
}
orderBy=
{
orderBy
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment