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
0b85cb56
Commit
0b85cb56
authored
Feb 01, 2025
by
johnnyjoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore(frontend): fix clsx
parent
57014e39
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
111 additions
and
120 deletions
+111
-120
ActivityCalendar.tsx
web/src/components/ActivityCalendar.tsx
+3
-4
BaseDialog.tsx
web/src/components/Dialog/BaseDialog.tsx
+3
-3
ExploreSidebar.tsx
web/src/components/ExploreSidebar/ExploreSidebar.tsx
+2
-2
HomeSidebar.tsx
web/src/components/HomeSidebar/HomeSidebar.tsx
+2
-2
TagsSection.tsx
web/src/components/HomeSidebar/TagsSection.tsx
+2
-2
MemoCommentMessage.tsx
web/src/components/Inbox/MemoCommentMessage.tsx
+3
-3
VersionUpdateMessage.tsx
web/src/components/Inbox/VersionUpdateMessage.tsx
+3
-3
MemoActionMenu.tsx
web/src/components/MemoActionMenu.tsx
+2
-2
CodeBlock.tsx
web/src/components/MemoContent/CodeBlock.tsx
+3
-3
EmbeddedMemo.tsx
...c/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx
+2
-2
EmbeddedResource.tsx
...mponents/MemoContent/EmbeddedContent/EmbeddedResource.tsx
+2
-2
List.tsx
web/src/components/MemoContent/List.tsx
+2
-2
Math.tsx
web/src/components/MemoContent/Math.tsx
+2
-2
Spoiler.tsx
web/src/components/MemoContent/Spoiler.tsx
+3
-3
Tag.tsx
web/src/components/MemoContent/Tag.tsx
+2
-5
TaskListItem.tsx
web/src/components/MemoContent/TaskListItem.tsx
+3
-3
index.tsx
web/src/components/MemoContent/index.tsx
+2
-2
MemoDetailSidebar.tsx
web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx
+3
-6
MemoDisplaySettingMenu.tsx
web/src/components/MemoDisplaySettingMenu.tsx
+2
-2
TagSuggestions.tsx
web/src/components/MemoEditor/Editor/TagSuggestions.tsx
+2
-2
index.tsx
web/src/components/MemoEditor/Editor/index.tsx
+2
-5
MemoFilters.tsx
web/src/components/MemoFilters.tsx
+3
-3
MemoRelationForceGraph.tsx
...ponents/MemoRelationForceGraph/MemoRelationForceGraph.tsx
+2
-2
MemoRelationListView.tsx
web/src/components/MemoRelationListView.tsx
+3
-3
MemoView.tsx
web/src/components/MemoView.tsx
+3
-3
MobileHeader.tsx
web/src/components/MobileHeader.tsx
+2
-2
Navigation.tsx
web/src/components/Navigation.tsx
+3
-3
ReactionSelector.tsx
web/src/components/ReactionSelector.tsx
+3
-3
ReactionView.tsx
web/src/components/ReactionView.tsx
+2
-2
ResourceIcon.tsx
web/src/components/ResourceIcon.tsx
+4
-4
StatisticsView.tsx
web/src/components/StatisticsView.tsx
+5
-5
UserAvatar.tsx
web/src/components/UserAvatar.tsx
+2
-2
UserBanner.tsx
web/src/components/UserBanner.tsx
+2
-2
VisibilityIcon.tsx
web/src/components/VisibilityIcon.tsx
+2
-2
OverflowTip.tsx
web/src/components/kit/OverflowTip.tsx
+2
-2
Popover.tsx
web/src/components/ui/Popover.tsx
+3
-3
RootLayout.tsx
web/src/layouts/RootLayout.tsx
+5
-5
en.json
web/src/locales/en.json
+3
-3
Explore.tsx
web/src/pages/Explore.tsx
+3
-3
Home.tsx
web/src/pages/Home.tsx
+3
-3
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+3
-3
index.ts
web/src/utils/index.ts
+1
-0
utils.ts
web/src/utils/utils.ts
+2
-2
No files found.
web/src/components/ActivityCalendar.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
cn
}
from
"@/utils/utils"
;
interface
Props
{
interface
Props
{
month
:
string
;
// Format: 2021-1
month
:
string
;
// Format: 2021-1
...
@@ -66,9 +65,9 @@ const ActivityCalendar = (props: Props) => {
...
@@ -66,9 +65,9 @@ const ActivityCalendar = (props: Props) => {
}
}
return
(
return
(
<
div
className=
{
c
lsx
(
"w-full h-auto shrink-0 grid grid-cols-7 grid-flow-row gap-1"
)
}
>
<
div
className=
{
c
n
(
"w-full h-auto shrink-0 grid grid-cols-7 grid-flow-row gap-1"
)
}
>
{
weekDays
.
map
((
day
,
index
)
=>
(
{
weekDays
.
map
((
day
,
index
)
=>
(
<
div
key=
{
index
}
className=
{
c
lsx
(
"w-6 h-5 text-xs flex justify-center items-center cursor-default opacity-60"
)
}
>
<
div
key=
{
index
}
className=
{
c
n
(
"w-6 h-5 text-xs flex justify-center items-center cursor-default opacity-60"
)
}
>
{
day
}
{
day
}
</
div
>
</
div
>
))
}
))
}
...
...
web/src/components/Dialog/BaseDialog.tsx
View file @
0b85cb56
import
{
CssVarsProvider
}
from
"@mui/joy"
;
import
{
CssVarsProvider
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
useEffect
,
useRef
}
from
"react"
;
import
{
useEffect
,
useRef
}
from
"react"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
Provider
}
from
"react-redux"
;
import
{
Provider
}
from
"react-redux"
;
...
@@ -7,6 +6,7 @@ import CommonContextProvider from "@/layouts/CommonContextProvider";
...
@@ -7,6 +6,7 @@ import CommonContextProvider from "@/layouts/CommonContextProvider";
import
store
from
"@/store"
;
import
store
from
"@/store"
;
import
{
useDialogStore
}
from
"@/store/module"
;
import
{
useDialogStore
}
from
"@/store/module"
;
import
theme
from
"@/theme"
;
import
theme
from
"@/theme"
;
import
{
cn
}
from
"@/utils"
;
import
"@/less/base-dialog.less"
;
import
"@/less/base-dialog.less"
;
interface
DialogConfig
{
interface
DialogConfig
{
...
@@ -56,8 +56,8 @@ const BaseDialog: React.FC<Props> = (props: Props) => {
...
@@ -56,8 +56,8 @@ const BaseDialog: React.FC<Props> = (props: Props) => {
};
};
return
(
return
(
<
div
className=
{
c
lsx
(
"dialog-wrapper"
,
className
)
}
onMouseDown=
{
handleSpaceClicked
}
>
<
div
className=
{
c
n
(
"dialog-wrapper"
,
className
)
}
onMouseDown=
{
handleSpaceClicked
}
>
<
div
ref=
{
dialogContainerRef
}
className=
{
c
lsx
(
"dialog-container"
)
}
onMouseDown=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
<
div
ref=
{
dialogContainerRef
}
className=
{
c
n
(
"dialog-container"
)
}
onMouseDown=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
{
children
}
{
children
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/ExploreSidebar/ExploreSidebar.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
{
useUserStatsStore
}
from
"@/store/v1"
;
import
{
useUserStatsStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
TagsSection
from
"../HomeSidebar/TagsSection"
;
import
TagsSection
from
"../HomeSidebar/TagsSection"
;
import
StatisticsView
from
"../StatisticsView"
;
import
StatisticsView
from
"../StatisticsView"
;
...
@@ -22,7 +22,7 @@ const ExploreSidebar = (props: Props) => {
...
@@ -22,7 +22,7 @@ const ExploreSidebar = (props: Props) => {
return
(
return
(
<
aside
<
aside
className=
{
c
lsx
(
className=
{
c
n
(
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
props
.
className
,
props
.
className
,
)
}
)
}
...
...
web/src/components/HomeSidebar/HomeSidebar.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
StatisticsView
from
"@/components/StatisticsView"
;
import
StatisticsView
from
"@/components/StatisticsView"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoList
,
useUserStatsStore
}
from
"@/store/v1"
;
import
{
useMemoList
,
useUserStatsStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
TagsSection
from
"./TagsSection"
;
import
TagsSection
from
"./TagsSection"
;
interface
Props
{
interface
Props
{
...
@@ -25,7 +25,7 @@ const HomeSidebar = (props: Props) => {
...
@@ -25,7 +25,7 @@ const HomeSidebar = (props: Props) => {
return
(
return
(
<
aside
<
aside
className=
{
c
lsx
(
className=
{
c
n
(
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
props
.
className
,
props
.
className
,
)
}
)
}
...
...
web/src/components/HomeSidebar/TagsSection.tsx
View file @
0b85cb56
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
,
Switch
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
,
Switch
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
Edit3Icon
,
HashIcon
,
MoreVerticalIcon
,
TagsIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
Edit3Icon
,
HashIcon
,
MoreVerticalIcon
,
TagsIcon
,
TrashIcon
}
from
"lucide-react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
useLocalStorage
from
"react-use/lib/useLocalStorage"
;
import
useLocalStorage
from
"react-use/lib/useLocalStorage"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
useMemoFilterStore
,
useUserStatsStore
,
useUserStatsTags
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
,
useUserStatsStore
,
useUserStatsTags
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
showRenameTagDialog
from
"../RenameTagDialog"
;
import
showRenameTagDialog
from
"../RenameTagDialog"
;
import
TagTree
from
"../TagTree"
;
import
TagTree
from
"../TagTree"
;
...
@@ -94,7 +94,7 @@ const TagsSection = (props: Props) => {
...
@@ -94,7 +94,7 @@ const TagsSection = (props: Props) => {
</
Menu
>
</
Menu
>
</
Dropdown
>
</
Dropdown
>
<
div
<
div
className=
{
c
lsx
(
"inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]"
)
}
className=
{
c
n
(
"inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]"
)
}
onClick=
{
()
=>
handleTagClick
(
tag
)
}
onClick=
{
()
=>
handleTagClick
(
tag
)
}
>
>
<
span
className=
"truncate dark:opacity-80"
>
{
tag
}
</
span
>
<
span
className=
"truncate dark:opacity-80"
>
{
tag
}
</
span
>
...
...
web/src/components/Inbox/MemoCommentMessage.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
InboxIcon
,
LoaderIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
InboxIcon
,
LoaderIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
...
@@ -10,6 +9,7 @@ import { activityNamePrefix, useInboxStore, useMemoStore, useUserStore } from "@
...
@@ -10,6 +9,7 @@ import { activityNamePrefix, useInboxStore, useMemoStore, useUserStore } from "@
import
{
Inbox
,
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
Inbox
,
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
User
}
from
"@/types/proto/api/v1/user_service"
;
import
{
User
}
from
"@/types/proto/api/v1/user_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
memoLink
}
from
"@/utils/memo"
;
...
@@ -74,7 +74,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
...
@@ -74,7 +74,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
return
(
return
(
<
div
className=
"w-full flex flex-row justify-start items-start gap-3"
>
<
div
className=
"w-full flex flex-row justify-start items-start gap-3"
>
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"shrink-0 mt-2 p-2 rounded-full border"
,
"shrink-0 mt-2 p-2 rounded-full border"
,
inbox
.
status
===
Inbox_Status
.
UNREAD
inbox
.
status
===
Inbox_Status
.
UNREAD
?
"border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
?
"border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
...
@@ -86,7 +86,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
...
@@ -86,7 +86,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
</
Tooltip
>
</
Tooltip
>
</
div
>
</
div
>
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700"
,
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700"
,
inbox
.
status
!==
Inbox_Status
.
UNREAD
&&
"opacity-60"
,
inbox
.
status
!==
Inbox_Status
.
UNREAD
&&
"opacity-60"
,
)
}
)
}
...
...
web/src/components/Inbox/VersionUpdateMessage.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
ArrowUpIcon
,
InboxIcon
}
from
"lucide-react"
;
import
{
ArrowUpIcon
,
InboxIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
...
@@ -7,6 +6,7 @@ import { activityServiceClient } from "@/grpcweb";
...
@@ -7,6 +6,7 @@ import { activityServiceClient } from "@/grpcweb";
import
{
activityNamePrefix
,
useInboxStore
}
from
"@/store/v1"
;
import
{
activityNamePrefix
,
useInboxStore
}
from
"@/store/v1"
;
import
{
Activity
}
from
"@/types/proto/api/v1/activity_service"
;
import
{
Activity
}
from
"@/types/proto/api/v1/activity_service"
;
import
{
Inbox
,
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
Inbox
,
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
interface
Props
{
interface
Props
{
...
@@ -58,7 +58,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
...
@@ -58,7 +58,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
return (
return (
<div className="w-full flex flex-row justify-start items-start gap-3">
<div className="w-full flex flex-row justify-start items-start gap-3">
<div
<div
className={c
lsx
(
className={c
n
(
"shrink-0 mt-2 p-2 rounded-full border",
"shrink-0 mt-2 p-2 rounded-full border",
inbox.status === Inbox_Status.UNREAD
inbox.status === Inbox_Status.UNREAD
? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
...
@@ -70,7 +70,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
...
@@ -70,7 +70,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
</Tooltip>
</Tooltip>
</div>
</div>
<div
<div
className={c
lsx
(
className={c
n
(
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700",
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700",
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
)}
)}
...
...
web/src/components/MemoActionMenu.tsx
View file @
0b85cb56
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
{
import
{
ArchiveIcon
,
ArchiveIcon
,
...
@@ -20,6 +19,7 @@ import { useMemoStore, useUserStatsStore } from "@/store/v1";
...
@@ -20,6 +19,7 @@ import { useMemoStore, useUserStatsStore } from "@/store/v1";
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
memoLink
}
from
"@/utils/memo"
;
...
@@ -166,7 +166,7 @@ const MemoActionMenu = (props: Props) => {
...
@@ -166,7 +166,7 @@ const MemoActionMenu = (props: Props) => {
return
(
return
(
<
Dropdown
>
<
Dropdown
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
span
className=
{
c
lsx
(
"flex justify-center items-center rounded-full hover:opacity-70"
,
props
.
className
)
}
>
<
span
className=
{
c
n
(
"flex justify-center items-center rounded-full hover:opacity-70"
,
props
.
className
)
}
>
<
MoreVerticalIcon
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
<
MoreVerticalIcon
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
</
span
>
</
span
>
</
MenuButton
>
</
MenuButton
>
...
...
web/src/components/MemoContent/CodeBlock.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
hljs
from
"highlight.js"
;
import
hljs
from
"highlight.js"
;
import
{
CopyIcon
}
from
"lucide-react"
;
import
{
CopyIcon
}
from
"lucide-react"
;
import
{
useCallback
,
useMemo
}
from
"react"
;
import
{
useCallback
,
useMemo
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
{
cn
}
from
"@/utils"
;
import
MermaidBlock
from
"./MermaidBlock"
;
import
MermaidBlock
from
"./MermaidBlock"
;
import
{
BaseProps
}
from
"./types"
;
import
{
BaseProps
}
from
"./types"
;
...
@@ -66,9 +66,9 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
...
@@ -66,9 +66,9 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
</
div
>
</
div
>
<
div
className=
"overflow-auto"
>
<
div
className=
"overflow-auto"
>
<
pre
className=
{
c
lsx
(
"no-wrap overflow-auto"
,
"w-full p-2 bg-amber-50 dark:bg-zinc-700 relative"
)
}
>
<
pre
className=
{
c
n
(
"no-wrap overflow-auto"
,
"w-full p-2 bg-amber-50 dark:bg-zinc-700 relative"
)
}
>
<
code
<
code
className=
{
c
lsx
(
`language-${formatedLanguage}`
,
"block text-sm leading-5"
)
}
className=
{
c
n
(
`language-${formatedLanguage}`
,
"block text-sm leading-5"
)
}
dangerouslySetInnerHTML=
{
{
__html
:
highlightedCode
}
}
dangerouslySetInnerHTML=
{
{
__html
:
highlightedCode
}
}
></
code
>
></
code
>
</
pre
>
</
pre
>
...
...
web/src/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
{
ArrowUpRightIcon
}
from
"lucide-react"
;
import
{
ArrowUpRightIcon
}
from
"lucide-react"
;
import
{
useContext
,
useEffect
}
from
"react"
;
import
{
useContext
,
useEffect
}
from
"react"
;
...
@@ -7,6 +6,7 @@ import { Link } from "react-router-dom";
...
@@ -7,6 +6,7 @@ import { Link } from "react-router-dom";
import
MemoResourceListView
from
"@/components/MemoResourceListView"
;
import
MemoResourceListView
from
"@/components/MemoResourceListView"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
{
extractMemoIdFromName
,
useMemoStore
}
from
"@/store/v1"
;
import
{
extractMemoIdFromName
,
useMemoStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
MemoContent
from
".."
;
import
MemoContent
from
".."
;
import
{
RendererContext
}
from
"../types"
;
import
{
RendererContext
}
from
"../types"
;
...
@@ -45,7 +45,7 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
...
@@ -45,7 +45,7 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
context
.
embeddedMemos
.
add
(
memoName
);
context
.
embeddedMemos
.
add
(
memoName
);
const
contentNode
=
useSnippet
?
(
const
contentNode
=
useSnippet
?
(
<
div
className=
{
c
lsx
(
"text-gray-800 dark:text-gray-400"
,
inlineMode
?
""
:
"line-clamp-3"
)
}
>
{
memo
.
snippet
}
</
div
>
<
div
className=
{
c
n
(
"text-gray-800 dark:text-gray-400"
,
inlineMode
?
""
:
"line-clamp-3"
)
}
>
{
memo
.
snippet
}
</
div
>
)
:
(
)
:
(
<>
<>
<
MemoContent
<
MemoContent
...
...
web/src/components/MemoContent/EmbeddedContent/EmbeddedResource.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
useEffect
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
MemoResourceListView
from
"@/components/MemoResourceListView"
;
import
MemoResourceListView
from
"@/components/MemoResourceListView"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
{
useResourceStore
}
from
"@/store/v1"
;
import
{
useResourceStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
Error
from
"./Error"
;
import
Error
from
"./Error"
;
interface
Props
{
interface
Props
{
...
@@ -53,7 +53,7 @@ const EmbeddedResource = ({ resourceId: uid, params: paramsStr }: Props) => {
...
@@ -53,7 +53,7 @@ const EmbeddedResource = ({ resourceId: uid, params: paramsStr }: Props) => {
}
}
return
(
return
(
<
div
className=
{
c
lsx
(
"max-w-full"
,
getAdditionalClassNameWithParams
(
params
))
}
>
<
div
className=
{
c
n
(
"max-w-full"
,
getAdditionalClassNameWithParams
(
params
))
}
>
<
MemoResourceListView
resources=
{
[
resource
]
}
/>
<
MemoResourceListView
resources=
{
[
resource
]
}
/>
</
div
>
</
div
>
);
);
...
...
web/src/components/MemoContent/List.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
head
}
from
"lodash-es"
;
import
{
head
}
from
"lodash-es"
;
import
React
from
"react"
;
import
React
from
"react"
;
import
{
ListNode_Kind
,
Node
,
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
ListNode_Kind
,
Node
,
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
cn
}
from
"@/utils"
;
import
Renderer
from
"./Renderer"
;
import
Renderer
from
"./Renderer"
;
interface
Props
{
interface
Props
{
...
@@ -43,7 +43,7 @@ const List: React.FC<Props> = ({ kind, indent, children }: Props) => {
...
@@ -43,7 +43,7 @@ const List: React.FC<Props> = ({ kind, indent, children }: Props) => {
return
React
.
createElement
(
return
React
.
createElement
(
getListContainer
(),
getListContainer
(),
{
{
className
:
c
lsx
(
className
:
c
n
(
`list-inside
${
kind
===
ListNode_Kind
.
ORDERED
?
"list-decimal"
:
kind
===
ListNode_Kind
.
UNORDERED
?
"list-disc"
:
"list-none"
}
`
,
`list-inside
${
kind
===
ListNode_Kind
.
ORDERED
?
"list-decimal"
:
kind
===
ListNode_Kind
.
UNORDERED
?
"list-disc"
:
"list-none"
}
`
,
indent
>
0
?
`pl-
${
2
*
indent
}
`
:
""
,
indent
>
0
?
`pl-
${
2
*
indent
}
`
:
""
,
),
),
...
...
web/src/components/MemoContent/Math.tsx
View file @
0b85cb56
import
TeX
from
"@matejmazur/react-katex"
;
import
TeX
from
"@matejmazur/react-katex"
;
import
clsx
from
"clsx"
;
import
"katex/dist/katex.min.css"
;
import
"katex/dist/katex.min.css"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
content
:
string
;
content
:
string
;
...
@@ -8,7 +8,7 @@ interface Props {
...
@@ -8,7 +8,7 @@ interface Props {
}
}
const
Math
:
React
.
FC
<
Props
>
=
({
content
,
block
}:
Props
)
=>
{
const
Math
:
React
.
FC
<
Props
>
=
({
content
,
block
}:
Props
)
=>
{
return
<
TeX
className=
{
c
lsx
(
"max-w-full"
,
block
?
"w-full block"
:
"inline text-sm"
)
}
block=
{
block
}
math=
{
content
}
></
TeX
>;
return
<
TeX
className=
{
c
n
(
"max-w-full"
,
block
?
"w-full block"
:
"inline text-sm"
)
}
block=
{
block
}
math=
{
content
}
></
TeX
>;
};
};
export
default
Math
;
export
default
Math
;
web/src/components/MemoContent/Spoiler.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
content
:
string
;
content
:
string
;
...
@@ -10,10 +10,10 @@ const Spoiler: React.FC<Props> = ({ content }: Props) => {
...
@@ -10,10 +10,10 @@ const Spoiler: React.FC<Props> = ({ content }: Props) => {
return
(
return
(
<
span
<
span
className=
{
c
lsx
(
"inline cursor-pointer select-none"
,
isRevealed
?
""
:
"bg-gray-200 dark:bg-zinc-700"
)
}
className=
{
c
n
(
"inline cursor-pointer select-none"
,
isRevealed
?
""
:
"bg-gray-200 dark:bg-zinc-700"
)
}
onClick=
{
()
=>
setIsRevealed
(
!
isRevealed
)
}
onClick=
{
()
=>
setIsRevealed
(
!
isRevealed
)
}
>
>
<
span
className=
{
c
lsx
(
isRevealed
?
"opacity-100"
:
"opacity-0"
)
}
>
{
content
}
</
span
>
<
span
className=
{
c
n
(
isRevealed
?
"opacity-100"
:
"opacity-0"
)
}
>
{
content
}
</
span
>
</
span
>
</
span
>
);
);
};
};
...
...
web/src/components/MemoContent/Tag.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
useContext
}
from
"react"
;
import
{
useContext
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
Routes
}
from
"@/router"
;
import
{
Routes
}
from
"@/router"
;
import
{
stringifyFilters
,
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
stringifyFilters
,
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
RendererContext
}
from
"./types"
;
import
{
RendererContext
}
from
"./types"
;
interface
Props
{
interface
Props
{
...
@@ -44,10 +44,7 @@ const Tag: React.FC<Props> = ({ content }: Props) => {
...
@@ -44,10 +44,7 @@ const Tag: React.FC<Props> = ({ content }: Props) => {
return
(
return
(
<
span
<
span
className=
{
clsx
(
className=
{
cn
(
"inline-block w-auto text-blue-600 dark:text-blue-400"
,
context
.
disableFilter
?
""
:
"cursor-pointer hover:opacity-80"
)
}
"inline-block w-auto text-blue-600 dark:text-blue-400"
,
context
.
disableFilter
?
""
:
"cursor-pointer hover:opacity-80"
,
)
}
onClick=
{
handleTagClick
}
onClick=
{
handleTagClick
}
>
>
#
{
content
}
#
{
content
}
...
...
web/src/components/MemoContent/TaskListItem.tsx
View file @
0b85cb56
import
{
Checkbox
}
from
"@usememos/mui"
;
import
{
Checkbox
}
from
"@usememos/mui"
;
import
clsx
from
"clsx"
;
import
{
useContext
,
useState
}
from
"react"
;
import
{
useContext
,
useState
}
from
"react"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
Node
,
TaskListItemNode
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
Node
,
TaskListItemNode
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
cn
}
from
"@/utils"
;
import
Renderer
from
"./Renderer"
;
import
Renderer
from
"./Renderer"
;
import
{
RendererContext
}
from
"./types"
;
import
{
RendererContext
}
from
"./types"
;
...
@@ -39,11 +39,11 @@ const TaskListItem: React.FC<Props> = ({ node, complete, children }: Props) => {
...
@@ -39,11 +39,11 @@ const TaskListItem: React.FC<Props> = ({ node, complete, children }: Props) => {
};
};
return
(
return
(
<
li
className=
{
c
lsx
(
"w-full grid grid-cols-[24px_1fr]"
)
}
>
<
li
className=
{
c
n
(
"w-full grid grid-cols-[24px_1fr]"
)
}
>
<
span
className=
"w-6 h-6 flex justify-start items-center"
>
<
span
className=
"w-6 h-6 flex justify-start items-center"
>
<
Checkbox
size=
"sm"
checked=
{
checked
}
disabled=
{
context
.
readonly
}
onChange=
{
(
e
)
=>
handleCheckboxChange
(
e
.
target
.
checked
)
}
/>
<
Checkbox
size=
"sm"
checked=
{
checked
}
disabled=
{
context
.
readonly
}
onChange=
{
(
e
)
=>
handleCheckboxChange
(
e
.
target
.
checked
)
}
/>
</
span
>
</
span
>
<
p
className=
{
c
lsx
(
complete
&&
"line-through opacity-80"
)
}
>
<
p
className=
{
c
n
(
complete
&&
"line-through opacity-80"
)
}
>
{
children
.
map
((
child
,
index
)
=>
(
{
children
.
map
((
child
,
index
)
=>
(
<
Renderer
key=
{
`${child.type}-${index}`
}
index=
{
String
(
index
)
}
node=
{
child
}
/>
<
Renderer
key=
{
`${child.type}-${index}`
}
index=
{
String
(
index
)
}
node=
{
child
}
/>
))
}
))
}
...
...
web/src/components/MemoContent/index.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
Node
,
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
Node
,
NodeType
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
isSuperUser
}
from
"@/utils/user"
;
import
{
isSuperUser
}
from
"@/utils/user"
;
import
Renderer
from
"./Renderer"
;
import
Renderer
from
"./Renderer"
;
...
@@ -86,7 +86,7 @@ const MemoContent: React.FC<Props> = (props: Props) => {
...
@@ -86,7 +86,7 @@ const MemoContent: React.FC<Props> = (props: Props) => {
<
div
className=
{
`w-full flex flex-col justify-start items-start text-gray-800 dark:text-gray-400 ${className || ""}`
}
>
<
div
className=
{
`w-full flex flex-col justify-start items-start text-gray-800 dark:text-gray-400 ${className || ""}`
}
>
<
div
<
div
ref=
{
memoContentContainerRef
}
ref=
{
memoContentContainerRef
}
className=
{
c
lsx
(
className=
{
c
n
(
"relative w-full max-w-full word-break text-base leading-snug space-y-2 whitespace-pre-wrap"
,
"relative w-full max-w-full word-break text-base leading-snug space-y-2 whitespace-pre-wrap"
,
showCompactMode
==
"ALL"
&&
"line-clamp-6 max-h-60"
,
showCompactMode
==
"ALL"
&&
"line-clamp-6 max-h-60"
,
contentClassName
,
contentClassName
,
...
...
web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
CheckCircleIcon
,
Code2Icon
,
HashIcon
,
LinkIcon
}
from
"lucide-react"
;
import
{
CheckCircleIcon
,
Code2Icon
,
HashIcon
,
LinkIcon
}
from
"lucide-react"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
Memo
,
MemoProperty
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
,
MemoProperty
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
MemoRelationForceGraph
from
"../MemoRelationForceGraph"
;
import
MemoRelationForceGraph
from
"../MemoRelationForceGraph"
;
...
@@ -20,10 +20,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
...
@@ -20,10 +20,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
return
(
return
(
<
aside
<
aside
className=
{
clsx
(
className=
{
cn
(
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
className
)
}
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start"
,
className
,
)
}
>
>
<
div
className=
"flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
{
shouldShowRelationGraph
&&
(
{
shouldShowRelationGraph
&&
(
...
@@ -95,7 +92,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
...
@@ -95,7 +92,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
className=
"shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
className=
"shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
>
>
<
HashIcon
className=
"group-hover:hidden w-4 h-auto shrink-0 opacity-40"
/>
<
HashIcon
className=
"group-hover:hidden w-4 h-auto shrink-0 opacity-40"
/>
<
div
className=
{
c
lsx
(
"inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]"
)
}
>
<
div
className=
{
c
n
(
"inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]"
)
}
>
<
span
className=
"truncate dark:opacity-80"
>
{
tag
}
</
span
>
<
span
className=
"truncate dark:opacity-80"
>
{
tag
}
</
span
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/MemoDisplaySettingMenu.tsx
View file @
0b85cb56
import
{
Option
,
Select
}
from
"@mui/joy"
;
import
{
Option
,
Select
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
Settings2Icon
}
from
"lucide-react"
;
import
{
Settings2Icon
}
from
"lucide-react"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
Popover
,
PopoverContent
,
PopoverTrigger
}
from
"./ui/Popover"
;
import
{
Popover
,
PopoverContent
,
PopoverTrigger
}
from
"./ui/Popover"
;
...
@@ -17,7 +17,7 @@ const MemoDisplaySettingMenu = ({ className }: Props) => {
...
@@ -17,7 +17,7 @@ const MemoDisplaySettingMenu = ({ className }: Props) => {
return
(
return
(
<
Popover
>
<
Popover
>
<
PopoverTrigger
<
PopoverTrigger
className=
{
c
lsx
(
className
,
isApplying
?
"text-teal-600 bg-teal-50 dark:text-teal-500 dark:bg-teal-900 rounded-sm"
:
"opacity-40"
)
}
className=
{
c
n
(
className
,
isApplying
?
"text-teal-600 bg-teal-50 dark:text-teal-500 dark:bg-teal-900 rounded-sm"
:
"opacity-40"
)
}
>
>
<
Settings2Icon
className=
"w-4 h-auto shrink-0"
/>
<
Settings2Icon
className=
"w-4 h-auto shrink-0"
/>
</
PopoverTrigger
>
</
PopoverTrigger
>
...
...
web/src/components/MemoEditor/Editor/TagSuggestions.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
Fuse
from
"fuse.js"
;
import
Fuse
from
"fuse.js"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
getCaretCoordinates
from
"textarea-caret"
;
import
getCaretCoordinates
from
"textarea-caret"
;
import
OverflowTip
from
"@/components/kit/OverflowTip"
;
import
OverflowTip
from
"@/components/kit/OverflowTip"
;
import
{
useUserStatsTags
}
from
"@/store/v1"
;
import
{
useUserStatsTags
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
EditorRefActions
}
from
"."
;
import
{
EditorRefActions
}
from
"."
;
type
Props
=
{
type
Props
=
{
...
@@ -110,7 +110,7 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => {
...
@@ -110,7 +110,7 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => {
<
div
<
div
key=
{
tag
}
key=
{
tag
}
onMouseDown=
{
()
=>
autocomplete
(
tag
)
}
onMouseDown=
{
()
=>
autocomplete
(
tag
)
}
className=
{
c
lsx
(
className=
{
c
n
(
"rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800"
,
"rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800"
,
i
===
selected
?
"bg-zinc-300 dark:bg-zinc-600"
:
""
,
i
===
selected
?
"bg-zinc-300 dark:bg-zinc-600"
:
""
,
)
}
)
}
...
...
web/src/components/MemoEditor/Editor/index.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
last
}
from
"lodash-es"
;
import
{
last
}
from
"lodash-es"
;
import
{
forwardRef
,
ReactNode
,
useCallback
,
useEffect
,
useImperativeHandle
,
useRef
,
useState
}
from
"react"
;
import
{
forwardRef
,
ReactNode
,
useCallback
,
useEffect
,
useImperativeHandle
,
useRef
,
useState
}
from
"react"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
NodeType
,
OrderedListItemNode
,
TaskListItemNode
,
UnorderedListItemNode
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
NodeType
,
OrderedListItemNode
,
TaskListItemNode
,
UnorderedListItemNode
}
from
"@/types/proto/api/v1/markdown_service"
;
import
{
cn
}
from
"@/utils"
;
import
TagSuggestions
from
"./TagSuggestions"
;
import
TagSuggestions
from
"./TagSuggestions"
;
export
interface
EditorRefActions
{
export
interface
EditorRefActions
{
...
@@ -187,10 +187,7 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
...
@@ -187,10 +187,7 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
return
(
return
(
<
div
<
div
className=
{
clsx
(
className=
{
cn
(
"flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit dark:text-gray-300"
,
className
)
}
"flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit dark:text-gray-300"
,
className
,
)
}
>
>
<
textarea
<
textarea
className=
"w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none whitespace-pre-wrap word-break"
className=
"w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none whitespace-pre-wrap word-break"
...
...
web/src/components/MemoFilters.tsx
View file @
0b85cb56
...
@@ -75,15 +75,15 @@ const MemoFilters = () => {
...
@@ -75,15 +75,15 @@ const MemoFilters = () => {
return
(
return
(
<
div
className=
"w-full mb-2 flex flex-row justify-start items-start gap-2"
>
<
div
className=
"w-full mb-2 flex flex-row justify-start items-start gap-2"
>
<
span
className=
"flex flex-row items-center gap-0.5 text-gray-500 text-sm leading-
6
border border-transparent"
>
<
span
className=
"flex flex-row items-center gap-0.5 text-gray-500 text-sm leading-
7
border border-transparent"
>
<
FilterIcon
className=
"w-4 h-auto opacity-60 inline"
/>
<
FilterIcon
className=
"w-4 h-auto opacity-60 inline"
/>
{
t
(
"memo.filters"
)
}
{
t
(
"memo.filters"
)
}
</
span
>
</
span
>
<
div
className=
"flex flex-row justify-start items-center flex-wrap gap-
2 leading-6 h-6
"
>
<
div
className=
"flex flex-row justify-start items-center flex-wrap gap-
x-2 gap-y-1 leading-7 h-7
"
>
{
filters
.
map
((
filter
)
=>
(
{
filters
.
map
((
filter
)
=>
(
<
div
<
div
key=
{
getMemoFilterKey
(
filter
)
}
key=
{
getMemoFilterKey
(
filter
)
}
className=
"flex flex-row items-center gap-1 bg-white dark:bg-zinc-800 border dark:border-zinc-700 pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
className=
"
w-auto h-full
flex flex-row items-center gap-1 bg-white dark:bg-zinc-800 border dark:border-zinc-700 pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
onClick=
{
()
=>
memoFilterStore
.
removeFilter
((
f
)
=>
isEqual
(
f
,
filter
))
}
onClick=
{
()
=>
memoFilterStore
.
removeFilter
((
f
)
=>
isEqual
(
f
,
filter
))
}
>
>
<
FactorIcon
className=
"w-4 h-auto text-gray-500 dark:text-gray-400 opacity-60"
factor=
{
filter
.
factor
}
/>
<
FactorIcon
className=
"w-4 h-auto text-gray-500 dark:text-gray-400 opacity-60"
factor=
{
filter
.
factor
}
/>
...
...
web/src/components/MemoRelationForceGraph/MemoRelationForceGraph.tsx
View file @
0b85cb56
import
{
useColorScheme
}
from
"@mui/joy"
;
import
{
useColorScheme
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
ForceGraph2D
,
{
ForceGraphMethods
,
LinkObject
,
NodeObject
}
from
"react-force-graph-2d"
;
import
ForceGraph2D
,
{
ForceGraphMethods
,
LinkObject
,
NodeObject
}
from
"react-force-graph-2d"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
LinkType
,
NodeType
}
from
"./types"
;
import
{
LinkType
,
NodeType
}
from
"./types"
;
import
{
convertMemoRelationsToGraphData
}
from
"./utils"
;
import
{
convertMemoRelationsToGraphData
}
from
"./utils"
;
...
@@ -40,7 +40,7 @@ const MemoRelationForceGraph = ({ className, memo, parentPage }: Props) => {
...
@@ -40,7 +40,7 @@ const MemoRelationForceGraph = ({ className, memo, parentPage }: Props) => {
};
};
return
(
return
(
<
div
ref=
{
containerRef
}
className=
{
c
lsx
(
"dark:opacity-80"
,
className
)
}
>
<
div
ref=
{
containerRef
}
className=
{
c
n
(
"dark:opacity-80"
,
className
)
}
>
<
ForceGraph2D
<
ForceGraph2D
ref=
{
graphRef
}
ref=
{
graphRef
}
width=
{
graphSize
.
width
}
width=
{
graphSize
.
width
}
...
...
web/src/components/MemoRelationListView.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
LinkIcon
,
MilestoneIcon
}
from
"lucide-react"
;
import
{
LinkIcon
,
MilestoneIcon
}
from
"lucide-react"
;
import
{
memo
,
useState
}
from
"react"
;
import
{
memo
,
useState
}
from
"react"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
MemoRelation
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
MemoRelation
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
memo
:
Memo
;
memo
:
Memo
;
...
@@ -32,7 +32,7 @@ const MemoRelationListView = (props: Props) => {
...
@@ -32,7 +32,7 @@ const MemoRelationListView = (props: Props) => {
<
div
className=
"w-full flex flex-row justify-start items-center mb-1 gap-3 opacity-60"
>
<
div
className=
"w-full flex flex-row justify-start items-center mb-1 gap-3 opacity-60"
>
{
referencingMemoList
.
length
>
0
&&
(
{
referencingMemoList
.
length
>
0
&&
(
<
button
<
button
className=
{
c
lsx
(
className=
{
c
n
(
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500"
,
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500"
,
selectedTab
===
"referencing"
&&
"text-gray-800 dark:text-gray-400"
,
selectedTab
===
"referencing"
&&
"text-gray-800 dark:text-gray-400"
,
)
}
)
}
...
@@ -45,7 +45,7 @@ const MemoRelationListView = (props: Props) => {
...
@@ -45,7 +45,7 @@ const MemoRelationListView = (props: Props) => {
)
}
)
}
{
referencedMemoList
.
length
>
0
&&
(
{
referencedMemoList
.
length
>
0
&&
(
<
button
<
button
className=
{
c
lsx
(
className=
{
c
n
(
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500"
,
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500"
,
selectedTab
===
"referenced"
&&
"text-gray-800 dark:text-gray-400"
,
selectedTab
===
"referenced"
&&
"text-gray-800 dark:text-gray-400"
,
)
}
)
}
...
...
web/src/components/MemoView.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
BookmarkIcon
,
MessageCircleMoreIcon
}
from
"lucide-react"
;
import
{
BookmarkIcon
,
MessageCircleMoreIcon
}
from
"lucide-react"
;
import
{
memo
,
useCallback
,
useRef
,
useState
}
from
"react"
;
import
{
memo
,
useCallback
,
useRef
,
useState
}
from
"react"
;
import
{
Link
,
useLocation
}
from
"react-router-dom"
;
import
{
Link
,
useLocation
}
from
"react-router-dom"
;
...
@@ -12,6 +11,7 @@ import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
...
@@ -12,6 +11,7 @@ import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
import
{
Memo
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
convertVisibilityToString
,
memoLink
}
from
"@/utils/memo"
;
import
{
convertVisibilityToString
,
memoLink
}
from
"@/utils/memo"
;
import
{
isSuperUser
}
from
"@/utils/user"
;
import
{
isSuperUser
}
from
"@/utils/user"
;
...
@@ -125,7 +125,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
...
@@ -125,7 +125,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
return
(
return
(
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"group relative flex flex-col justify-start items-start w-full px-4 py-3 mb-2 gap-2 bg-white dark:bg-zinc-800 rounded-lg border border-white dark:border-zinc-800 hover:border-gray-200 dark:hover:border-zinc-700"
,
"group relative flex flex-col justify-start items-start w-full px-4 py-3 mb-2 gap-2 bg-white dark:bg-zinc-800 rounded-lg border border-white dark:border-zinc-800 hover:border-gray-200 dark:hover:border-zinc-700"
,
props
.
showPinned
&&
memo
.
pinned
&&
"border-gray-200 border dark:border-zinc-700"
,
props
.
showPinned
&&
memo
.
pinned
&&
"border-gray-200 border dark:border-zinc-700"
,
className
,
className
,
...
@@ -188,7 +188,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
...
@@ -188,7 +188,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
{
!
isInMemoDetailPage
&&
(
workspaceMemoRelatedSetting
.
enableComment
||
commentAmount
>
0
)
&&
(
{
!
isInMemoDetailPage
&&
(
workspaceMemoRelatedSetting
.
enableComment
||
commentAmount
>
0
)
&&
(
<
Link
<
Link
className=
{
c
lsx
(
className=
{
c
n
(
"flex flex-row justify-start items-center hover:opacity-70"
,
"flex flex-row justify-start items-center hover:opacity-70"
,
commentAmount
===
0
&&
"invisible group-hover:visible"
,
commentAmount
===
0
&&
"invisible group-hover:visible"
,
)
}
)
}
...
...
web/src/components/MobileHeader.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
useWindowScroll
from
"react-use/lib/useWindowScroll"
;
import
useWindowScroll
from
"react-use/lib/useWindowScroll"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
import
NavigationDrawer
from
"./NavigationDrawer"
;
import
NavigationDrawer
from
"./NavigationDrawer"
;
interface
Props
{
interface
Props
{
...
@@ -21,7 +21,7 @@ const MobileHeader = (props: Props) => {
...
@@ -21,7 +21,7 @@ const MobileHeader = (props: Props) => {
return
(
return
(
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-zinc-100 dark:bg-zinc-900 bg-opacity-80 backdrop-blur-lg flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1"
,
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-zinc-100 dark:bg-zinc-900 bg-opacity-80 backdrop-blur-lg flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1"
,
offsetTop
>
0
&&
"shadow-md"
,
offsetTop
>
0
&&
"shadow-md"
,
className
,
className
,
...
...
web/src/components/Navigation.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
ArchiveIcon
,
BellIcon
,
Globe2Icon
,
HomeIcon
,
LogInIcon
,
PaperclipIcon
,
SettingsIcon
,
SmileIcon
,
User2Icon
}
from
"lucide-react"
;
import
{
ArchiveIcon
,
BellIcon
,
Globe2Icon
,
HomeIcon
,
LogInIcon
,
PaperclipIcon
,
SettingsIcon
,
SmileIcon
,
User2Icon
}
from
"lucide-react"
;
import
{
useEffect
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
NavLink
}
from
"react-router-dom"
;
import
{
NavLink
}
from
"react-router-dom"
;
...
@@ -7,6 +6,7 @@ import useCurrentUser from "@/hooks/useCurrentUser";
...
@@ -7,6 +6,7 @@ import useCurrentUser from "@/hooks/useCurrentUser";
import
{
Routes
}
from
"@/router"
;
import
{
Routes
}
from
"@/router"
;
import
{
useInboxStore
}
from
"@/store/v1"
;
import
{
useInboxStore
}
from
"@/store/v1"
;
import
{
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
Inbox_Status
}
from
"@/types/proto/api/v1/inbox_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
UserBanner
from
"./UserBanner"
;
import
UserBanner
from
"./UserBanner"
;
...
@@ -116,14 +116,14 @@ const Navigation = (props: Props) => {
...
@@ -116,14 +116,14 @@ const Navigation = (props: Props) => {
return
(
return
(
<
header
<
header
className=
{
c
lsx
(
"w-full h-full overflow-auto flex flex-col justify-start items-start py-4 md:pt-6 z-30 hide-scrollbar"
,
className
)
}
className=
{
c
n
(
"w-full h-full overflow-auto flex flex-col justify-start items-start py-4 md:pt-6 z-30 hide-scrollbar"
,
className
)
}
>
>
<
UserBanner
collapsed=
{
collapsed
}
/>
<
UserBanner
collapsed=
{
collapsed
}
/>
<
div
className=
"w-full px-1 py-2 flex flex-col justify-start items-start shrink-0 space-y-2"
>
<
div
className=
"w-full px-1 py-2 flex flex-col justify-start items-start shrink-0 space-y-2"
>
{
navLinks
.
map
((
navLink
)
=>
(
{
navLinks
.
map
((
navLink
)
=>
(
<
NavLink
<
NavLink
className=
{
({
isActive
})
=>
className=
{
({
isActive
})
=>
c
lsx
(
c
n
(
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-400 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800"
,
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-400 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800"
,
collapsed
?
""
:
"w-full px-4"
,
collapsed
?
""
:
"w-full px-4"
,
isActive
?
"bg-white drop-shadow-sm dark:bg-zinc-800 border-gray-200 dark:border-zinc-700"
:
"border-transparent"
,
isActive
?
"bg-white drop-shadow-sm dark:bg-zinc-800 border-gray-200 dark:border-zinc-700"
:
"border-transparent"
,
...
...
web/src/components/ReactionSelector.tsx
View file @
0b85cb56
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
SmilePlusIcon
}
from
"lucide-react"
;
import
{
SmilePlusIcon
}
from
"lucide-react"
;
import
{
useRef
,
useState
}
from
"react"
;
import
{
useRef
,
useState
}
from
"react"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
...
@@ -9,6 +8,7 @@ import { useMemoStore, useWorkspaceSettingStore } from "@/store/v1";
...
@@ -9,6 +8,7 @@ import { useMemoStore, useWorkspaceSettingStore } from "@/store/v1";
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
memo
:
Memo
;
memo
:
Memo
;
...
@@ -63,7 +63,7 @@ const ReactionSelector = (props: Props) => {
...
@@ -63,7 +63,7 @@ const ReactionSelector = (props: Props) => {
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
span
<
span
className=
{
c
lsx
(
"h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70"
,
className
)
}
className=
{
c
n
(
"h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70"
,
className
)
}
>
>
<
SmilePlusIcon
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
<
SmilePlusIcon
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
</
span
>
</
span
>
...
@@ -75,7 +75,7 @@ const ReactionSelector = (props: Props) => {
...
@@ -75,7 +75,7 @@ const ReactionSelector = (props: Props) => {
return
(
return
(
<
span
<
span
key=
{
reactionType
}
key=
{
reactionType
}
className=
{
c
lsx
(
className=
{
c
n
(
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-gray-500 dark:text-gray-400 hover:opacity-80"
,
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-gray-500 dark:text-gray-400 hover:opacity-80"
,
hasReacted
(
reactionType
)
&&
"bg-blue-100 dark:bg-zinc-800"
,
hasReacted
(
reactionType
)
&&
"bg-blue-100 dark:bg-zinc-800"
,
)
}
)
}
...
...
web/src/components/ReactionView.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
User
}
from
"@/types/proto/api/v1/user_service"
;
import
{
User
}
from
"@/types/proto/api/v1/user_service"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
memo
:
Memo
;
memo
:
Memo
;
...
@@ -67,7 +67,7 @@ const ReactionView = (props: Props) => {
...
@@ -67,7 +67,7 @@ const ReactionView = (props: Props) => {
return
(
return
(
<
Tooltip
title=
{
stringifyUsers
(
users
,
reactionType
)
}
placement=
"top"
>
<
Tooltip
title=
{
stringifyUsers
(
users
,
reactionType
)
}
placement=
"top"
>
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"h-7 border px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1 dark:border-zinc-700"
,
"h-7 border px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1 dark:border-zinc-700"
,
"text-sm text-gray-600 dark:text-gray-400"
,
"text-sm text-gray-600 dark:text-gray-400"
,
currentUser
&&
!
readonly
&&
"cursor-pointer"
,
currentUser
&&
!
readonly
&&
"cursor-pointer"
,
...
...
web/src/components/ResourceIcon.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
import
{
BinaryIcon
,
BinaryIcon
,
BookIcon
,
BookIcon
,
...
@@ -12,6 +11,7 @@ import {
...
@@ -12,6 +11,7 @@ import {
}
from
"lucide-react"
;
}
from
"lucide-react"
;
import
React
from
"react"
;
import
React
from
"react"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
getResourceType
,
getResourceUrl
}
from
"@/utils/resource"
;
import
{
getResourceType
,
getResourceUrl
}
from
"@/utils/resource"
;
import
showPreviewImageDialog
from
"./PreviewImageDialog"
;
import
showPreviewImageDialog
from
"./PreviewImageDialog"
;
import
SquareDiv
from
"./kit/SquareDiv"
;
import
SquareDiv
from
"./kit/SquareDiv"
;
...
@@ -26,7 +26,7 @@ const ResourceIcon = (props: Props) => {
...
@@ -26,7 +26,7 @@ const ResourceIcon = (props: Props) => {
const
{
resource
}
=
props
;
const
{
resource
}
=
props
;
const
resourceType
=
getResourceType
(
resource
);
const
resourceType
=
getResourceType
(
resource
);
const
resourceUrl
=
getResourceUrl
(
resource
);
const
resourceUrl
=
getResourceUrl
(
resource
);
const
className
=
c
lsx
(
"w-full h-auto"
,
props
.
className
);
const
className
=
c
n
(
"w-full h-auto"
,
props
.
className
);
const
strokeWidth
=
props
.
strokeWidth
;
const
strokeWidth
=
props
.
strokeWidth
;
const
previewResource
=
()
=>
{
const
previewResource
=
()
=>
{
...
@@ -35,7 +35,7 @@ const ResourceIcon = (props: Props) => {
...
@@ -35,7 +35,7 @@ const ResourceIcon = (props: Props) => {
if
(
resourceType
===
"image/*"
)
{
if
(
resourceType
===
"image/*"
)
{
return
(
return
(
<
SquareDiv
className=
{
c
lsx
(
className
,
"flex items-center justify-center overflow-clip"
)
}
>
<
SquareDiv
className=
{
c
n
(
className
,
"flex items-center justify-center overflow-clip"
)
}
>
<
img
<
img
className=
"min-w-full min-h-full object-cover"
className=
"min-w-full min-h-full object-cover"
src=
{
resource
.
externalLink
?
resourceUrl
:
resourceUrl
+
"?thumbnail=true"
}
src=
{
resource
.
externalLink
?
resourceUrl
:
resourceUrl
+
"?thumbnail=true"
}
...
@@ -73,7 +73,7 @@ const ResourceIcon = (props: Props) => {
...
@@ -73,7 +73,7 @@ const ResourceIcon = (props: Props) => {
};
};
return
(
return
(
<
div
onClick=
{
previewResource
}
className=
{
c
lsx
(
className
,
"max-w-[4rem] opacity-50"
)
}
>
<
div
onClick=
{
previewResource
}
className=
{
c
n
(
className
,
"max-w-[4rem] opacity-50"
)
}
>
{
getResourceIcon
()
}
{
getResourceIcon
()
}
</
div
>
</
div
>
);
);
...
...
web/src/components/StatisticsView.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
countBy
}
from
"lodash-es"
;
import
{
countBy
}
from
"lodash-es"
;
import
{
CheckCircleIcon
,
ChevronDownIcon
,
ChevronUpIcon
,
Code2Icon
,
LinkIcon
,
ListTodoIcon
}
from
"lucide-react"
;
import
{
CheckCircleIcon
,
ChevronDownIcon
,
ChevronUpIcon
,
Code2Icon
,
LinkIcon
,
ListTodoIcon
}
from
"lucide-react"
;
...
@@ -8,6 +7,7 @@ import useAsyncEffect from "@/hooks/useAsyncEffect";
...
@@ -8,6 +7,7 @@ import useAsyncEffect from "@/hooks/useAsyncEffect";
import
i18n
from
"@/i18n"
;
import
i18n
from
"@/i18n"
;
import
{
useMemoFilterStore
,
useUserStatsStore
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
,
useUserStatsStore
}
from
"@/store/v1"
;
import
{
UserStats_MemoTypeStats
}
from
"@/types/proto/api/v1/user_service"
;
import
{
UserStats_MemoTypeStats
}
from
"@/types/proto/api/v1/user_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
ActivityCalendar
from
"./ActivityCalendar"
;
import
ActivityCalendar
from
"./ActivityCalendar"
;
...
@@ -42,7 +42,7 @@ const StatisticsView = () => {
...
@@ -42,7 +42,7 @@ const StatisticsView = () => {
};
};
return
(
return
(
<
div
className=
"group w-full mt-
2 py-2
space-y-1 text-gray-500 dark:text-gray-400"
>
<
div
className=
"group w-full mt-
4
space-y-1 text-gray-500 dark:text-gray-400"
>
<
div
className=
"w-full mb-1 flex flex-row justify-between items-center gap-1"
>
<
div
className=
"w-full mb-1 flex flex-row justify-between items-center gap-1"
>
<
div
className=
"relative text-sm font-medium inline-flex flex-row items-center w-auto dark:text-gray-400 truncate"
>
<
div
className=
"relative text-sm font-medium inline-flex flex-row items-center w-auto dark:text-gray-400 truncate"
>
<
span
className=
"truncate"
>
<
span
className=
"truncate"
>
...
@@ -74,7 +74,7 @@ const StatisticsView = () => {
...
@@ -74,7 +74,7 @@ const StatisticsView = () => {
</
div
>
</
div
>
<
div
className=
"pt-1 w-full flex flex-row justify-start items-center gap-x-2 gap-y-1 flex-wrap"
>
<
div
className=
"pt-1 w-full flex flex-row justify-start items-center gap-x-2 gap-y-1 flex-wrap"
>
<
div
<
div
className=
{
c
lsx
(
"w-auto border dark:border-zinc-800 pl-1 pr-1
.5 rounded-md flex justify-between items-center"
)
}
className=
{
c
n
(
"w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0
.5 rounded-md flex justify-between items-center"
)
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasLink"
,
value
:
""
})
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasLink"
,
value
:
""
})
}
>
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
...
@@ -84,7 +84,7 @@ const StatisticsView = () => {
...
@@ -84,7 +84,7 @@ const StatisticsView = () => {
<
span
className=
"text-sm truncate"
>
{
memoTypeStats
.
linkCount
}
</
span
>
<
span
className=
"text-sm truncate"
>
{
memoTypeStats
.
linkCount
}
</
span
>
</
div
>
</
div
>
<
div
<
div
className=
{
c
lsx
(
"w-auto border dark:border-zinc-800 pl-1 pr-1
.5 rounded-md flex justify-between items-center"
)
}
className=
{
c
n
(
"w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0
.5 rounded-md flex justify-between items-center"
)
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasTaskList"
,
value
:
""
})
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasTaskList"
,
value
:
""
})
}
>
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
...
@@ -104,7 +104,7 @@ const StatisticsView = () => {
...
@@ -104,7 +104,7 @@ const StatisticsView = () => {
)
}
)
}
</
div
>
</
div
>
<
div
<
div
className=
{
c
lsx
(
"w-auto border dark:border-zinc-800 pl-1 pr-1
.5 rounded-md flex justify-between items-center"
)
}
className=
{
c
n
(
"w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0
.5 rounded-md flex justify-between items-center"
)
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasCode"
,
value
:
""
})
}
onClick=
{
()
=>
memoFilterStore
.
addFilter
({
factor
:
"property.hasCode"
,
value
:
""
})
}
>
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
<
div
className=
"w-auto flex justify-start items-center mr-1"
>
...
...
web/src/components/UserAvatar.tsx
View file @
0b85cb56
import
clsx
from
"clsx
"
;
import
{
cn
}
from
"@/utils
"
;
interface
Props
{
interface
Props
{
avatarUrl
?:
string
;
avatarUrl
?:
string
;
...
@@ -8,7 +8,7 @@ interface Props {
...
@@ -8,7 +8,7 @@ interface Props {
const
UserAvatar
=
(
props
:
Props
)
=>
{
const
UserAvatar
=
(
props
:
Props
)
=>
{
const
{
avatarUrl
,
className
}
=
props
;
const
{
avatarUrl
,
className
}
=
props
;
return
(
return
(
<
div
className=
{
c
lsx
(
`w-8 h-8 overflow-clip rounded-xl`
,
className
)
}
>
<
div
className=
{
c
n
(
`w-8 h-8 overflow-clip rounded-xl`
,
className
)
}
>
<
img
<
img
className=
"w-full h-auto shadow min-w-full min-h-full object-cover dark:opacity-80"
className=
"w-full h-auto shadow min-w-full min-h-full object-cover dark:opacity-80"
src=
{
avatarUrl
||
"/full-logo.webp"
}
src=
{
avatarUrl
||
"/full-logo.webp"
}
...
...
web/src/components/UserBanner.tsx
View file @
0b85cb56
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
LogOutIcon
,
SmileIcon
}
from
"lucide-react"
;
import
{
LogOutIcon
,
SmileIcon
}
from
"lucide-react"
;
import
{
authServiceClient
}
from
"@/grpcweb"
;
import
{
authServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
...
@@ -8,6 +7,7 @@ import { Routes } from "@/router";
...
@@ -8,6 +7,7 @@ import { Routes } from "@/router";
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
UserAvatar
from
"./UserAvatar"
;
import
UserAvatar
from
"./UserAvatar"
;
...
@@ -36,7 +36,7 @@ const UserBanner = (props: Props) => {
...
@@ -36,7 +36,7 @@ const UserBanner = (props: Props) => {
<
Dropdown
>
<
Dropdown
>
<
MenuButton
disabled=
{
!
user
}
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
disabled=
{
!
user
}
slots=
{
{
root
:
"div"
}
}
>
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer text-gray-800 dark:text-gray-400"
,
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer text-gray-800 dark:text-gray-400"
,
collapsed
?
"px-1"
:
"px-3"
,
collapsed
?
"px-1"
:
"px-3"
,
)
}
)
}
...
...
web/src/components/VisibilityIcon.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
{
Globe2Icon
,
LockIcon
,
UsersIcon
}
from
"lucide-react"
;
import
{
Globe2Icon
,
LockIcon
,
UsersIcon
}
from
"lucide-react"
;
import
{
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
visibility
:
Visibility
;
visibility
:
Visibility
;
...
@@ -21,7 +21,7 @@ const VisibilityIcon = (props: Props) => {
...
@@ -21,7 +21,7 @@ const VisibilityIcon = (props: Props) => {
return
null
;
return
null
;
}
}
return
<
VIcon
className=
{
c
lsx
(
"w-4 h-auto text-gray-500 dark:text-gray-400"
)
}
/>;
return
<
VIcon
className=
{
c
n
(
"w-4 h-auto text-gray-500 dark:text-gray-400"
)
}
/>;
};
};
export
default
VisibilityIcon
;
export
default
VisibilityIcon
;
web/src/components/kit/OverflowTip.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
useRef
,
useState
,
useEffect
}
from
"react"
;
import
{
useRef
,
useState
,
useEffect
}
from
"react"
;
import
{
cn
}
from
"@/utils"
;
interface
Props
{
interface
Props
{
children
:
React
.
ReactNode
;
children
:
React
.
ReactNode
;
...
@@ -21,7 +21,7 @@ const OverflowTip = ({ children, className }: Props) => {
...
@@ -21,7 +21,7 @@ const OverflowTip = ({ children, className }: Props) => {
return
(
return
(
<
Tooltip
title=
{
children
}
placement=
"top"
arrow
disableHoverListener=
{
!
isOverflowed
}
>
<
Tooltip
title=
{
children
}
placement=
"top"
arrow
disableHoverListener=
{
!
isOverflowed
}
>
<
div
ref=
{
textElementRef
}
className=
{
c
lsx
(
"truncate"
,
className
)
}
>
<
div
ref=
{
textElementRef
}
className=
{
c
n
(
"truncate"
,
className
)
}
>
{
children
}
{
children
}
</
div
>
</
div
>
</
Tooltip
>
</
Tooltip
>
...
...
web/src/components/ui/Popover.tsx
View file @
0b85cb56
import
*
as
PopoverPrimitive
from
"@radix-ui/react-popover"
;
import
*
as
PopoverPrimitive
from
"@radix-ui/react-popover"
;
import
clsx
from
"clsx"
;
import
*
as
React
from
"react"
;
import
*
as
React
from
"react"
;
import
{
cn
}
from
"@/utils"
;
const
Popover
=
PopoverPrimitive
.
Root
;
const
Popover
=
PopoverPrimitive
.
Root
;
...
@@ -16,8 +16,8 @@ const PopoverContent = React.forwardRef<
...
@@ -16,8 +16,8 @@ const PopoverContent = React.forwardRef<
ref=
{
ref
}
ref=
{
ref
}
align=
{
align
}
align=
{
align
}
sideOffset=
{
sideOffset
}
sideOffset=
{
sideOffset
}
className=
{
c
lsx
(
className=
{
c
n
(
"z-[2000] w-auto rounded-md bg-white dark:bg-zinc-900 border dark:border-zinc-800
bg-popover p-2 text-popover-foreground
shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
,
"z-[2000] w-auto rounded-md bg-white dark:bg-zinc-900 border dark:border-zinc-800
p-2
shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
,
className
,
className
,
)
}
)
}
{
...
props
}
{
...
props
}
...
...
web/src/layouts/RootLayout.tsx
View file @
0b85cb56
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
Button
}
from
"@usememos/mui"
;
import
clsx
from
"clsx"
;
import
{
ChevronLeftIcon
,
ChevronRightIcon
}
from
"lucide-react"
;
import
{
ChevronLeftIcon
,
ChevronRightIcon
}
from
"lucide-react"
;
import
{
Suspense
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
{
Suspense
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
{
Outlet
,
useLocation
,
useSearchParams
}
from
"react-router-dom"
;
import
{
Outlet
,
useLocation
,
useSearchParams
}
from
"react-router-dom"
;
...
@@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
...
@@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
import
Loading
from
"@/pages/Loading"
;
import
Loading
from
"@/pages/Loading"
;
import
{
Routes
}
from
"@/router"
;
import
{
Routes
}
from
"@/router"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
const
RootLayout
=
()
=>
{
const
RootLayout
=
()
=>
{
...
@@ -47,18 +47,18 @@ const RootLayout = () => {
...
@@ -47,18 +47,18 @@ const RootLayout = () => {
<
Loading
/>
<
Loading
/>
)
:
(
)
:
(
<
div
className=
"w-full min-h-full"
>
<
div
className=
"w-full min-h-full"
>
<
div
className=
{
c
lsx
(
"w-full transition-all mx-auto flex flex-row justify-center items-start"
,
collapsed
?
"sm:pl-16"
:
"sm:pl-56"
)
}
>
<
div
className=
{
c
n
(
"w-full transition-all mx-auto flex flex-row justify-center items-start"
,
collapsed
?
"sm:pl-16"
:
"sm:pl-56"
)
}
>
{
sm
&&
(
{
sm
&&
(
<
div
<
div
className=
{
c
lsx
(
className=
{
c
n
(
"group flex flex-col justify-start items-start fixed top-0 left-0 select-none border-r dark:border-zinc-800 h-full bg-zinc-50 dark:bg-zinc-800 dark:bg-opacity-40 transition-all hover:shadow-xl z-2"
,
"group flex flex-col justify-start items-start fixed top-0 left-0 select-none border-r dark:border-zinc-800 h-full bg-zinc-50 dark:bg-zinc-800 dark:bg-opacity-40 transition-all hover:shadow-xl z-2"
,
collapsed
?
"w-16 px-2"
:
"w-56 px-4"
,
collapsed
?
"w-16 px-2"
:
"w-56 px-4"
,
)
}
)
}
>
>
<
Navigation
className=
"!h-auto"
collapsed=
{
collapsed
}
/>
<
Navigation
className=
"!h-auto"
collapsed=
{
collapsed
}
/>
<
div
className=
{
c
lsx
(
"w-full grow h-auto flex flex-col justify-end"
,
collapsed
?
"items-center"
:
"items-start"
)
}
>
<
div
className=
{
c
n
(
"w-full grow h-auto flex flex-col justify-end"
,
collapsed
?
"items-center"
:
"items-start"
)
}
>
<
div
<
div
className=
{
c
lsx
(
"hidden py-3 group-hover:flex flex-col justify-center items-center"
)
}
className=
{
c
n
(
"hidden py-3 group-hover:flex flex-col justify-center items-center"
)
}
onClick=
{
()
=>
setCollapsed
(
!
collapsed
)
}
onClick=
{
()
=>
setCollapsed
(
!
collapsed
)
}
>
>
{
!
collapsed
?
(
{
!
collapsed
?
(
...
...
web/src/locales/en.json
View file @
0b85cb56
...
@@ -354,8 +354,8 @@
...
@@ -354,8 +354,8 @@
"workspace-section"
:
{
"workspace-section"
:
{
"disallow-user-registration"
:
"Disallow user registration"
,
"disallow-user-registration"
:
"Disallow user registration"
,
"disallow-password-auth"
:
"Disallow password auth"
,
"disallow-password-auth"
:
"Disallow password auth"
,
"disallow-change-username"
:
"Disallow
Change U
sername"
,
"disallow-change-username"
:
"Disallow
changing u
sername"
,
"disallow-change-nickname"
:
"Disallow
Change N
ickname"
,
"disallow-change-nickname"
:
"Disallow
changing n
ickname"
,
"week-start-day"
:
"Week start day"
,
"week-start-day"
:
"Week start day"
,
"saturday"
:
"Saturday"
,
"saturday"
:
"Saturday"
,
"sunday"
:
"Sunday"
,
"sunday"
:
"Sunday"
,
...
@@ -391,4 +391,4 @@
...
@@ -391,4 +391,4 @@
"blogs"
:
"Blogs"
,
"blogs"
:
"Blogs"
,
"documents"
:
"Documents"
"documents"
:
"Documents"
}
}
}
}
\ No newline at end of file
web/src/pages/Explore.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
useMemo
}
from
"react"
;
import
{
useMemo
}
from
"react"
;
import
{
ExploreSidebar
,
ExploreSidebarDrawer
}
from
"@/components/ExploreSidebar"
;
import
{
ExploreSidebar
,
ExploreSidebarDrawer
}
from
"@/components/ExploreSidebar"
;
...
@@ -11,6 +10,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
...
@@ -11,6 +10,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
const
Explore
=
()
=>
{
const
Explore
=
()
=>
{
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
...
@@ -59,8 +59,8 @@ const Explore = () => {
...
@@ -59,8 +59,8 @@ const Explore = () => {
<
ExploreSidebarDrawer
/>
<
ExploreSidebarDrawer
/>
</
MobileHeader
>
</
MobileHeader
>
)
}
)
}
<
div
className=
{
c
lsx
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
n
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
lsx
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
<
div
className=
{
c
n
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
<
MemoFilters
/>
<
MemoFilters
/>
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
<
PagedMemoList
<
PagedMemoList
...
...
web/src/pages/Home.tsx
View file @
0b85cb56
import
clsx
from
"clsx"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
useMemo
}
from
"react"
;
import
{
useMemo
}
from
"react"
;
import
{
HomeSidebar
,
HomeSidebarDrawer
}
from
"@/components/HomeSidebar"
;
import
{
HomeSidebar
,
HomeSidebarDrawer
}
from
"@/components/HomeSidebar"
;
...
@@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
...
@@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
useMemoFilterStore
}
from
"@/store/v1"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
const
Home
=
()
=>
{
const
Home
=
()
=>
{
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
...
@@ -60,8 +60,8 @@ const Home = () => {
...
@@ -60,8 +60,8 @@ const Home = () => {
<
HomeSidebarDrawer
/>
<
HomeSidebarDrawer
/>
</
MobileHeader
>
</
MobileHeader
>
)
}
)
}
<
div
className=
{
c
lsx
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
n
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
lsx
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
<
div
className=
{
c
n
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
<
MemoEditor
className=
"mb-2"
cacheKey=
"home-memo-editor"
/>
<
MemoEditor
className=
"mb-2"
cacheKey=
"home-memo-editor"
/>
<
MemoFilters
/>
<
MemoFilters
/>
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
...
...
web/src/pages/MemoDetail.tsx
View file @
0b85cb56
import
{
Button
}
from
"@usememos/mui"
;
import
{
Button
}
from
"@usememos/mui"
;
import
clsx
from
"clsx"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
...
@@ -16,6 +15,7 @@ import { memoNamePrefix, useMemoStore, useWorkspaceSettingStore } from "@/store/
...
@@ -16,6 +15,7 @@ import { memoNamePrefix, useMemoStore, useWorkspaceSettingStore } from "@/store/
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
WorkspaceMemoRelatedSetting
,
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceMemoRelatedSetting
,
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
memoLink
}
from
"@/utils/memo"
;
import
{
memoLink
}
from
"@/utils/memo"
;
...
@@ -92,8 +92,8 @@ const MemoDetail = () => {
...
@@ -92,8 +92,8 @@ const MemoDetail = () => {
<
MemoDetailSidebarDrawer
memo=
{
memo
}
parentPage=
{
locationState
?.
from
}
/>
<
MemoDetailSidebarDrawer
memo=
{
memo
}
parentPage=
{
locationState
?.
from
}
/>
</
MobileHeader
>
</
MobileHeader
>
)
}
)
}
<
div
className=
{
c
lsx
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
n
(
"w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4"
)
}
>
<
div
className=
{
c
lsx
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
<
div
className=
{
c
n
(
md
?
"w-[calc(100%-15rem)]"
:
"w-full"
)
}
>
{
parentMemo
&&
(
{
parentMemo
&&
(
<
div
className=
"w-auto inline-block mb-2"
>
<
div
className=
"w-auto inline-block mb-2"
>
<
Link
<
Link
...
...
web/src/utils/index.ts
0 → 100644
View file @
0b85cb56
export
*
from
"./utils"
;
web/src/utils/utils.ts
View file @
0b85cb56
import
{
type
ClassValue
,
clsx
}
from
"clsx"
;
import
{
type
ClassValue
,
clsx
}
from
"clsx"
;
import
{
twMerge
}
from
"tailwind-merge"
;
import
{
twMerge
}
from
"tailwind-merge"
;
export
function
cn
(...
inputs
:
ClassValue
[])
{
export
const
cn
=
(...
inputs
:
ClassValue
[])
=>
{
return
twMerge
(
clsx
(
inputs
));
return
twMerge
(
clsx
(
inputs
));
}
}
;
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