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
785c250f
Commit
785c250f
authored
May 27, 2025
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: migrate memo store
parent
dcd68bc5
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
206 additions
and
192 deletions
+206
-192
HomeSidebar.tsx
web/src/components/HomeSidebar/HomeSidebar.tsx
+2
-4
MemoCommentMessage.tsx
web/src/components/Inbox/MemoCommentMessage.tsx
+4
-5
MemoActionMenu.tsx
web/src/components/MemoActionMenu.tsx
+4
-4
EmbeddedMemo.tsx
...c/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx
+4
-4
ReferencedMemo.tsx
...mponents/MemoContent/ReferencedContent/ReferencedMemo.tsx
+4
-4
TaskListItem.tsx
web/src/components/MemoContent/TaskListItem.tsx
+4
-4
index.tsx
web/src/components/MemoContent/index.tsx
+4
-4
RelationListView.tsx
web/src/components/MemoEditor/RelationListView.tsx
+4
-4
index.tsx
web/src/components/MemoEditor/index.tsx
+1
-3
MemoView.tsx
web/src/components/MemoView.tsx
+4
-4
PagedMemoList.tsx
web/src/components/PagedMemoList/PagedMemoList.tsx
+3
-6
ReactionSelector.tsx
web/src/components/ReactionSelector.tsx
+4
-4
ReactionView.tsx
web/src/components/ReactionView.tsx
+4
-4
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+4
-4
Resources.tsx
web/src/pages/Resources.tsx
+4
-4
index.ts
web/src/store/v1/index.ts
+0
-1
memo.ts
web/src/store/v1/memo.ts
+0
-128
index.ts
web/src/store/v2/index.ts
+2
-1
memo.ts
web/src/store/v2/memo.ts
+150
-0
No files found.
web/src/components/HomeSidebar/HomeSidebar.tsx
View file @
785c250f
...
@@ -6,8 +6,7 @@ import useDebounce from "react-use/lib/useDebounce";
...
@@ -6,8 +6,7 @@ import useDebounce from "react-use/lib/useDebounce";
import
SearchBar
from
"@/components/SearchBar"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
Routes
}
from
"@/router"
;
import
{
Routes
}
from
"@/router"
;
import
{
useMemoList
}
from
"@/store/v1"
;
import
{
memoStore
,
userStore
}
from
"@/store/v2"
;
import
{
userStore
}
from
"@/store/v2"
;
import
{
cn
}
from
"@/utils"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
MemoFilters
from
"../MemoFilters"
;
import
MemoFilters
from
"../MemoFilters"
;
...
@@ -30,7 +29,6 @@ const HomeSidebar = observer((props: Props) => {
...
@@ -30,7 +29,6 @@ const HomeSidebar = observer((props: Props) => {
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
location
=
useLocation
();
const
location
=
useLocation
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
memoList
=
useMemoList
();
const
homeNavLink
:
NavLinkItem
=
{
const
homeNavLink
:
NavLinkItem
=
{
id
:
"header-home"
,
id
:
"header-home"
,
...
@@ -61,7 +59,7 @@ const HomeSidebar = observer((props: Props) => {
...
@@ -61,7 +59,7 @@ const HomeSidebar = observer((props: Props) => {
await
userStore
.
fetchUserStats
(
parent
);
await
userStore
.
fetchUserStats
(
parent
);
},
},
300
,
300
,
[
memo
List
.
size
()
,
userStore
.
state
.
statsStateId
,
location
.
pathname
],
[
memo
Store
.
state
.
memos
.
length
,
userStore
.
state
.
statsStateId
,
location
.
pathname
],
);
);
return
(
return
(
...
...
web/src/components/Inbox/MemoCommentMessage.tsx
View file @
785c250f
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
InboxIcon
,
LoaderIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
InboxIcon
,
LoaderIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
{
activityServiceClient
}
from
"@/grpcweb"
;
import
{
activityServiceClient
}
from
"@/grpcweb"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
activityNamePrefix
}
from
"@/store/common"
;
import
{
activityNamePrefix
}
from
"@/store/common"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
memoStore
,
userStore
}
from
"@/store/v2"
;
import
{
userStore
}
from
"@/store/v2"
;
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"
;
...
@@ -18,10 +18,9 @@ interface Props {
...
@@ -18,10 +18,9 @@ interface Props {
inbox
:
Inbox
;
inbox
:
Inbox
;
}
}
const
MemoCommentMessage
=
({
inbox
}:
Props
)
=>
{
const
MemoCommentMessage
=
observer
(
({
inbox
}:
Props
)
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
memoStore
=
useMemoStore
();
const
[
relatedMemo
,
setRelatedMemo
]
=
useState
<
Memo
|
undefined
>
(
undefined
);
const
[
relatedMemo
,
setRelatedMemo
]
=
useState
<
Memo
|
undefined
>
(
undefined
);
const
[
sender
,
setSender
]
=
useState
<
User
|
undefined
>
(
undefined
);
const
[
sender
,
setSender
]
=
useState
<
User
|
undefined
>
(
undefined
);
const
[
initialized
,
setInitialized
]
=
useState
<
boolean
>
(
false
);
const
[
initialized
,
setInitialized
]
=
useState
<
boolean
>
(
false
);
...
@@ -124,6 +123,6 @@ const MemoCommentMessage = ({ inbox }: Props) => {
...
@@ -124,6 +123,6 @@ const MemoCommentMessage = ({ inbox }: Props) => {
</
div
>
</
div
>
</
div
>
</
div
>
);
);
};
}
)
;
export
default
MemoCommentMessage
;
export
default
MemoCommentMessage
;
web/src/components/MemoActionMenu.tsx
View file @
785c250f
...
@@ -11,11 +11,12 @@ import {
...
@@ -11,11 +11,12 @@ import {
TrashIcon
,
TrashIcon
,
SquareCheckIcon
,
SquareCheckIcon
,
}
from
"lucide-react"
;
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
userStore
}
from
"@/store/v2"
;
import
{
userStore
}
from
"@/store/v2"
;
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"
;
...
@@ -43,12 +44,11 @@ const checkHasCompletedTaskList = (memo: Memo) => {
...
@@ -43,12 +44,11 @@ const checkHasCompletedTaskList = (memo: Memo) => {
return
false
;
return
false
;
};
};
const
MemoActionMenu
=
(
props
:
Props
)
=>
{
const
MemoActionMenu
=
observer
(
(
props
:
Props
)
=>
{
const
{
memo
,
readonly
}
=
props
;
const
{
memo
,
readonly
}
=
props
;
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
location
=
useLocation
();
const
location
=
useLocation
();
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
memoStore
=
useMemoStore
();
const
hasCompletedTaskList
=
checkHasCompletedTaskList
(
memo
);
const
hasCompletedTaskList
=
checkHasCompletedTaskList
(
memo
);
const
isInMemoDetailPage
=
location
.
pathname
.
startsWith
(
`/
${
memo
.
name
}
`
);
const
isInMemoDetailPage
=
location
.
pathname
.
startsWith
(
`/
${
memo
.
name
}
`
);
const
isComment
=
Boolean
(
memo
.
parent
);
const
isComment
=
Boolean
(
memo
.
parent
);
...
@@ -212,6 +212,6 @@ const MemoActionMenu = (props: Props) => {
...
@@ -212,6 +212,6 @@ const MemoActionMenu = (props: Props) => {
</
Menu
>
</
Menu
>
</
Dropdown
>
</
Dropdown
>
);
);
};
}
)
;
export
default
MemoActionMenu
;
export
default
MemoActionMenu
;
web/src/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx
View file @
785c250f
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
{
ArrowUpRightIcon
}
from
"lucide-react"
;
import
{
ArrowUpRightIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useContext
,
useEffect
}
from
"react"
;
import
{
useContext
,
useEffect
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
{
Link
}
from
"react-router-dom"
;
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
}
from
"@/store/common"
;
import
{
extractMemoIdFromName
}
from
"@/store/common"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
cn
}
from
"@/utils"
;
import
{
cn
}
from
"@/utils"
;
import
MemoContent
from
".."
;
import
MemoContent
from
".."
;
import
{
RendererContext
}
from
"../types"
;
import
{
RendererContext
}
from
"../types"
;
...
@@ -17,10 +18,9 @@ interface Props {
...
@@ -17,10 +18,9 @@ interface Props {
params
:
string
;
params
:
string
;
}
}
const
EmbeddedMemo
=
({
resourceId
:
uid
,
params
:
paramsStr
}:
Props
)
=>
{
const
EmbeddedMemo
=
observer
(
({
resourceId
:
uid
,
params
:
paramsStr
}:
Props
)
=>
{
const
context
=
useContext
(
RendererContext
);
const
context
=
useContext
(
RendererContext
);
const
loadingState
=
useLoading
();
const
loadingState
=
useLoading
();
const
memoStore
=
useMemoStore
();
const
memoName
=
`memos/
${
uid
}
`
;
const
memoName
=
`memos/
${
uid
}
`
;
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
...
@@ -87,6 +87,6 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
...
@@ -87,6 +87,6 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
{
contentNode
}
{
contentNode
}
</
div
>
</
div
>
);
);
};
}
)
;
export
default
EmbeddedMemo
;
export
default
EmbeddedMemo
;
web/src/components/MemoContent/ReferencedContent/ReferencedMemo.tsx
View file @
785c250f
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useContext
,
useEffect
}
from
"react"
;
import
{
useContext
,
useEffect
}
from
"react"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
memoNamePrefix
}
from
"@/store/common"
;
import
{
memoNamePrefix
}
from
"@/store/common"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
RendererContext
}
from
"../types"
;
import
{
RendererContext
}
from
"../types"
;
import
Error
from
"./Error"
;
import
Error
from
"./Error"
;
...
@@ -11,10 +12,9 @@ interface Props {
...
@@ -11,10 +12,9 @@ interface Props {
params
:
string
;
params
:
string
;
}
}
const
ReferencedMemo
=
({
resourceId
:
uid
,
params
:
paramsStr
}:
Props
)
=>
{
const
ReferencedMemo
=
observer
(
({
resourceId
:
uid
,
params
:
paramsStr
}:
Props
)
=>
{
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
loadingState
=
useLoading
();
const
loadingState
=
useLoading
();
const
memoStore
=
useMemoStore
();
const
memoName
=
`
${
memoNamePrefix
}${
uid
}
`
;
const
memoName
=
`
${
memoNamePrefix
}${
uid
}
`
;
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
const
params
=
new
URLSearchParams
(
paramsStr
);
const
params
=
new
URLSearchParams
(
paramsStr
);
...
@@ -50,6 +50,6 @@ const ReferencedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
...
@@ -50,6 +50,6 @@ const ReferencedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
{
displayContent
}
{
displayContent
}
</
span
>
</
span
>
);
);
};
}
)
;
export
default
ReferencedMemo
;
export
default
ReferencedMemo
;
web/src/components/MemoContent/TaskListItem.tsx
View file @
785c250f
import
{
Checkbox
}
from
"@usememos/mui"
;
import
{
Checkbox
}
from
"@usememos/mui"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useContext
}
from
"react"
;
import
{
useContext
}
from
"react"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
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
{
cn
}
from
"@/utils"
;
import
Renderer
from
"./Renderer"
;
import
Renderer
from
"./Renderer"
;
...
@@ -16,9 +17,8 @@ interface Props {
...
@@ -16,9 +17,8 @@ interface Props {
children
:
Node
[];
children
:
Node
[];
}
}
const
TaskListItem
:
React
.
FC
<
Props
>
=
({
node
,
complete
,
children
}:
Props
)
=>
{
const
TaskListItem
=
observer
(
({
node
,
complete
,
children
}:
Props
)
=>
{
const
context
=
useContext
(
RendererContext
);
const
context
=
useContext
(
RendererContext
);
const
memoStore
=
useMemoStore
();
const
handleCheckboxChange
=
async
(
on
:
boolean
)
=>
{
const
handleCheckboxChange
=
async
(
on
:
boolean
)
=>
{
if
(
context
.
readonly
||
!
context
.
memoName
)
{
if
(
context
.
readonly
||
!
context
.
memoName
)
{
...
@@ -48,6 +48,6 @@ const TaskListItem: React.FC<Props> = ({ node, complete, children }: Props) => {
...
@@ -48,6 +48,6 @@ const TaskListItem: React.FC<Props> = ({ node, complete, children }: Props) => {
</
p
>
</
p
>
</
li
>
</
li
>
);
);
};
}
)
;
export
default
TaskListItem
;
export
default
TaskListItem
;
web/src/components/MemoContent/index.tsx
View file @
785c250f
import
{
observer
}
from
"mobx-react-lite"
;
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
{
memoStore
}
from
"@/store/v2
"
;
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
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -29,11 +30,10 @@ interface Props {
...
@@ -29,11 +30,10 @@ interface Props {
type
ContentCompactView
=
"ALL"
|
"SNIPPET"
;
type
ContentCompactView
=
"ALL"
|
"SNIPPET"
;
const
MemoContent
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
MemoContent
=
observer
(
(
props
:
Props
)
=>
{
const
{
className
,
contentClassName
,
nodes
,
memoName
,
embeddedMemos
,
onClick
,
onDoubleClick
}
=
props
;
const
{
className
,
contentClassName
,
nodes
,
memoName
,
embeddedMemos
,
onClick
,
onDoubleClick
}
=
props
;
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
memoContentContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
memoContentContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
[
showCompactMode
,
setShowCompactMode
]
=
useState
<
ContentCompactView
|
undefined
>
(
undefined
);
const
[
showCompactMode
,
setShowCompactMode
]
=
useState
<
ContentCompactView
|
undefined
>
(
undefined
);
const
memo
=
memoName
?
memoStore
.
getMemoByName
(
memoName
)
:
null
;
const
memo
=
memoName
?
memoStore
.
getMemoByName
(
memoName
)
:
null
;
...
@@ -122,6 +122,6 @@ const MemoContent: React.FC<Props> = (props: Props) => {
...
@@ -122,6 +122,6 @@ const MemoContent: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
</
RendererContext
.
Provider
>
</
RendererContext
.
Provider
>
);
);
};
}
)
;
export
default
memo
(
MemoContent
);
export
default
memo
(
MemoContent
);
web/src/components/MemoEditor/RelationListView.tsx
View file @
785c250f
import
{
LinkIcon
,
XIcon
}
from
"lucide-react"
;
import
{
LinkIcon
,
XIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
Memo
,
MemoRelation
,
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
,
MemoRelation
,
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_service"
;
interface
Props
{
interface
Props
{
...
@@ -8,9 +9,8 @@ interface Props {
...
@@ -8,9 +9,8 @@ interface Props {
setRelationList
:
(
relationList
:
MemoRelation
[])
=>
void
;
setRelationList
:
(
relationList
:
MemoRelation
[])
=>
void
;
}
}
const
RelationListView
=
(
props
:
Props
)
=>
{
const
RelationListView
=
observer
(
(
props
:
Props
)
=>
{
const
{
relationList
,
setRelationList
}
=
props
;
const
{
relationList
,
setRelationList
}
=
props
;
const
memoStore
=
useMemoStore
();
const
[
referencingMemoList
,
setReferencingMemoList
]
=
useState
<
Memo
[]
>
([]);
const
[
referencingMemoList
,
setReferencingMemoList
]
=
useState
<
Memo
[]
>
([]);
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -50,6 +50,6 @@ const RelationListView = (props: Props) => {
...
@@ -50,6 +50,6 @@ const RelationListView = (props: Props) => {
)
}
)
}
</>
</>
);
);
};
}
)
;
export
default
RelationListView
;
export
default
RelationListView
;
web/src/components/MemoEditor/index.tsx
View file @
785c250f
...
@@ -13,8 +13,7 @@ import { TAB_SPACE_WIDTH } from "@/helpers/consts";
...
@@ -13,8 +13,7 @@ import { TAB_SPACE_WIDTH } from "@/helpers/consts";
import
{
isValidUrl
}
from
"@/helpers/utils"
;
import
{
isValidUrl
}
from
"@/helpers/utils"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoStore
}
from
"@/store/v1"
;
import
{
memoStore
,
resourceStore
,
userStore
,
workspaceStore
}
from
"@/store/v2"
;
import
{
resourceStore
,
userStore
,
workspaceStore
}
from
"@/store/v2"
;
import
{
Location
,
Memo
,
MemoRelation
,
MemoRelation_Type
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Location
,
Memo
,
MemoRelation
,
MemoRelation_Type
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
UserSetting
}
from
"@/types/proto/api/v1/user_service"
;
import
{
UserSetting
}
from
"@/types/proto/api/v1/user_service"
;
...
@@ -61,7 +60,6 @@ const MemoEditor = observer((props: Props) => {
...
@@ -61,7 +60,6 @@ const MemoEditor = observer((props: Props) => {
const
{
className
,
cacheKey
,
memoName
,
parentMemoName
,
autoFocus
,
onConfirm
,
onCancel
}
=
props
;
const
{
className
,
cacheKey
,
memoName
,
parentMemoName
,
autoFocus
,
onConfirm
,
onCancel
}
=
props
;
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
{
i18n
}
=
useTranslation
();
const
{
i18n
}
=
useTranslation
();
const
memoStore
=
useMemoStore
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
[
state
,
setState
]
=
useState
<
State
>
({
const
[
state
,
setState
]
=
useState
<
State
>
({
memoVisibility
:
Visibility
.
PRIVATE
,
memoVisibility
:
Visibility
.
PRIVATE
,
...
...
web/src/components/MemoView.tsx
View file @
785c250f
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
BookmarkIcon
,
EyeOffIcon
,
MessageCircleMoreIcon
}
from
"lucide-react"
;
import
{
BookmarkIcon
,
EyeOffIcon
,
MessageCircleMoreIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
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"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useAsyncEffect
from
"@/hooks/useAsyncEffect"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
userStore
,
workspaceStore
}
from
"@/store/v2"
;
import
{
userStore
,
workspaceStore
}
from
"@/store/v2"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
State
}
from
"@/types/proto/api/v1/common"
;
import
{
Memo
,
MemoRelation_Type
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
,
MemoRelation_Type
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
...
@@ -36,14 +37,13 @@ interface Props {
...
@@ -36,14 +37,13 @@ interface Props {
parentPage
?:
string
;
parentPage
?:
string
;
}
}
const
MemoView
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
MemoView
:
React
.
FC
<
Props
>
=
observer
(
(
props
:
Props
)
=>
{
const
{
memo
,
className
}
=
props
;
const
{
memo
,
className
}
=
props
;
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
location
=
useLocation
();
const
location
=
useLocation
();
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
user
=
useCurrentUser
();
const
user
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
[
showEditor
,
setShowEditor
]
=
useState
<
boolean
>
(
false
);
const
[
showEditor
,
setShowEditor
]
=
useState
<
boolean
>
(
false
);
const
[
creator
,
setCreator
]
=
useState
(
userStore
.
getUserByName
(
memo
.
creator
));
const
[
creator
,
setCreator
]
=
useState
(
userStore
.
getUserByName
(
memo
.
creator
));
const
[
showNSFWContent
,
setShowNSFWContent
]
=
useState
(
props
.
showNsfwContent
);
const
[
showNSFWContent
,
setShowNSFWContent
]
=
useState
(
props
.
showNsfwContent
);
...
@@ -250,6 +250,6 @@ const MemoView: React.FC<Props> = (props: Props) => {
...
@@ -250,6 +250,6 @@ const MemoView: React.FC<Props> = (props: Props) => {
)
}
)
}
</
div
>
</
div
>
);
);
};
}
)
;
export
default
memo
(
MemoView
);
export
default
memo
(
MemoView
);
web/src/components/PagedMemoList/PagedMemoList.tsx
View file @
785c250f
...
@@ -7,8 +7,7 @@ import PullToRefresh from "react-simple-pull-to-refresh";
...
@@ -7,8 +7,7 @@ import PullToRefresh from "react-simple-pull-to-refresh";
import
{
DEFAULT_LIST_MEMOS_PAGE_SIZE
}
from
"@/helpers/consts"
;
import
{
DEFAULT_LIST_MEMOS_PAGE_SIZE
}
from
"@/helpers/consts"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
{
Routes
}
from
"@/router"
;
import
{
Routes
}
from
"@/router"
;
import
{
useMemoList
,
useMemoStore
}
from
"@/store/v1"
;
import
{
memoStore
,
viewStore
}
from
"@/store/v2"
;
import
{
viewStore
}
from
"@/store/v2"
;
import
{
Direction
,
State
}
from
"@/types/proto/api/v1/common"
;
import
{
Direction
,
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
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -35,13 +34,11 @@ interface LocalState {
...
@@ -35,13 +34,11 @@ interface LocalState {
const
PagedMemoList
=
observer
((
props
:
Props
)
=>
{
const
PagedMemoList
=
observer
((
props
:
Props
)
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
const
memoStore
=
useMemoStore
();
const
memoList
=
useMemoList
();
const
[
state
,
setState
]
=
useState
<
LocalState
>
({
const
[
state
,
setState
]
=
useState
<
LocalState
>
({
isRequesting
:
true
,
// Initial request
isRequesting
:
true
,
// Initial request
nextPageToken
:
""
,
nextPageToken
:
""
,
});
});
const
sortedMemoList
=
props
.
listSort
?
props
.
listSort
(
memo
List
.
value
)
:
memoList
.
value
;
const
sortedMemoList
=
props
.
listSort
?
props
.
listSort
(
memo
Store
.
state
.
memos
)
:
memoStore
.
state
.
memos
;
const
showMemoEditor
=
Boolean
(
matchPath
(
Routes
.
ROOT
,
window
.
location
.
pathname
));
const
showMemoEditor
=
Boolean
(
matchPath
(
Routes
.
ROOT
,
window
.
location
.
pathname
));
const
fetchMoreMemos
=
async
(
nextPageToken
:
string
)
=>
{
const
fetchMoreMemos
=
async
(
nextPageToken
:
string
)
=>
{
...
@@ -62,7 +59,7 @@ const PagedMemoList = observer((props: Props) => {
...
@@ -62,7 +59,7 @@ const PagedMemoList = observer((props: Props) => {
};
};
const
refreshList
=
async
()
=>
{
const
refreshList
=
async
()
=>
{
memo
List
.
reset
();
memo
Store
.
state
.
updateStateId
();
setState
((
state
)
=>
({
...
state
,
nextPageToken
:
""
}));
setState
((
state
)
=>
({
...
state
,
nextPageToken
:
""
}));
await
fetchMoreMemos
(
""
);
await
fetchMoreMemos
(
""
);
};
};
...
...
web/src/components/ReactionSelector.tsx
View file @
785c250f
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
SmilePlusIcon
}
from
"lucide-react"
;
import
{
SmilePlusIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useRef
,
useState
}
from
"react"
;
import
{
useRef
,
useState
}
from
"react"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
workspaceStore
}
from
"@/store/v2"
;
import
{
workspaceStore
}
from
"@/store/v2"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
cn
}
from
"@/utils"
;
...
@@ -14,10 +15,9 @@ interface Props {
...
@@ -14,10 +15,9 @@ interface Props {
className
?:
string
;
className
?:
string
;
}
}
const
ReactionSelector
=
(
props
:
Props
)
=>
{
const
ReactionSelector
=
observer
(
(
props
:
Props
)
=>
{
const
{
memo
,
className
}
=
props
;
const
{
memo
,
className
}
=
props
;
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
[
open
,
setOpen
]
=
useState
(
false
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
containerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
containerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
workspaceMemoRelatedSetting
=
workspaceStore
.
state
.
memoRelatedSetting
;
const
workspaceMemoRelatedSetting
=
workspaceStore
.
state
.
memoRelatedSetting
;
...
@@ -86,6 +86,6 @@ const ReactionSelector = (props: Props) => {
...
@@ -86,6 +86,6 @@ const ReactionSelector = (props: Props) => {
</
Menu
>
</
Menu
>
</
Dropdown
>
</
Dropdown
>
);
);
};
}
)
;
export
default
ReactionSelector
;
export
default
ReactionSelector
;
web/src/components/ReactionView.tsx
View file @
785c250f
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
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"
;
...
@@ -28,10 +29,9 @@ const stringifyUsers = (users: User[], reactionType: string): string => {
...
@@ -28,10 +29,9 @@ const stringifyUsers = (users: User[], reactionType: string): string => {
);
);
};
};
const
ReactionView
=
(
props
:
Props
)
=>
{
const
ReactionView
=
observer
(
(
props
:
Props
)
=>
{
const
{
memo
,
reactionType
,
users
}
=
props
;
const
{
memo
,
reactionType
,
users
}
=
props
;
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
hasReaction
=
users
.
some
((
user
)
=>
currentUser
&&
user
.
username
===
currentUser
.
username
);
const
hasReaction
=
users
.
some
((
user
)
=>
currentUser
&&
user
.
username
===
currentUser
.
username
);
const
readonly
=
memo
.
state
===
State
.
ARCHIVED
;
const
readonly
=
memo
.
state
===
State
.
ARCHIVED
;
...
@@ -80,6 +80,6 @@ const ReactionView = (props: Props) => {
...
@@ -80,6 +80,6 @@ const ReactionView = (props: Props) => {
</
div
>
</
div
>
</
Tooltip
>
</
Tooltip
>
);
);
};
}
)
;
export
default
ReactionView
;
export
default
ReactionView
;
web/src/pages/MemoDetail.tsx
View file @
785c250f
import
{
Button
}
from
"@usememos/mui"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -12,20 +13,19 @@ import useCurrentUser from "@/hooks/useCurrentUser";
...
@@ -12,20 +13,19 @@ import useCurrentUser from "@/hooks/useCurrentUser";
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
{
memoNamePrefix
}
from
"@/store/common"
;
import
{
memoNamePrefix
}
from
"@/store/common"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
workspaceStore
}
from
"@/store/v2"
;
import
{
workspaceStore
}
from
"@/store/v2"
;
import
{
Memo
,
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
Memo
,
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
cn
}
from
"@/utils"
;
import
{
cn
}
from
"@/utils"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
const
MemoDetail
=
()
=>
{
const
MemoDetail
=
observer
(
()
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
const
params
=
useParams
();
const
params
=
useParams
();
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
{
state
:
locationState
}
=
useLocation
();
const
{
state
:
locationState
}
=
useLocation
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
uid
=
params
.
uid
;
const
uid
=
params
.
uid
;
const
memoName
=
`
${
memoNamePrefix
}${
uid
}
`
;
const
memoName
=
`
${
memoNamePrefix
}${
uid
}
`
;
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
const
memo
=
memoStore
.
getMemoByName
(
memoName
);
...
@@ -176,6 +176,6 @@ const MemoDetail = () => {
...
@@ -176,6 +176,6 @@ const MemoDetail = () => {
</
div
>
</
div
>
</
section
>
</
section
>
);
);
};
}
)
;
export
default
MemoDetail
;
export
default
MemoDetail
;
web/src/pages/Resources.tsx
View file @
785c250f
...
@@ -3,6 +3,7 @@ import { Button, Input } from "@usememos/mui";
...
@@ -3,6 +3,7 @@ import { Button, Input } from "@usememos/mui";
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
includes
}
from
"lodash-es"
;
import
{
includes
}
from
"lodash-es"
;
import
{
PaperclipIcon
,
SearchIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
PaperclipIcon
,
SearchIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
Empty
from
"@/components/Empty"
;
import
Empty
from
"@/components/Empty"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
...
@@ -11,7 +12,7 @@ import { resourceServiceClient } from "@/grpcweb";
...
@@ -11,7 +12,7 @@ import { resourceServiceClient } from "@/grpcweb";
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
i18n
from
"@/i18n"
;
import
i18n
from
"@/i18n"
;
import
{
useMemoStore
}
from
"@/store/v1
"
;
import
{
memoStore
}
from
"@/store/v2
"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
Resource
}
from
"@/types/proto/api/v1/resource_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -33,14 +34,13 @@ interface State {
...
@@ -33,14 +34,13 @@ interface State {
searchQuery
:
string
;
searchQuery
:
string
;
}
}
const
Resources
=
()
=>
{
const
Resources
=
observer
(
()
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
const
loadingState
=
useLoading
();
const
loadingState
=
useLoading
();
const
[
state
,
setState
]
=
useState
<
State
>
({
const
[
state
,
setState
]
=
useState
<
State
>
({
searchQuery
:
""
,
searchQuery
:
""
,
});
});
const
memoStore
=
useMemoStore
();
const
[
resources
,
setResources
]
=
useState
<
Resource
[]
>
([]);
const
[
resources
,
setResources
]
=
useState
<
Resource
[]
>
([]);
const
filteredResources
=
resources
.
filter
((
resource
)
=>
includes
(
resource
.
filename
,
state
.
searchQuery
));
const
filteredResources
=
resources
.
filter
((
resource
)
=>
includes
(
resource
.
filename
,
state
.
searchQuery
));
const
groupedResources
=
groupResourcesByDate
(
filteredResources
.
filter
((
resource
)
=>
resource
.
memo
));
const
groupedResources
=
groupResourcesByDate
(
filteredResources
.
filter
((
resource
)
=>
resource
.
memo
));
...
@@ -165,6 +165,6 @@ const Resources = () => {
...
@@ -165,6 +165,6 @@ const Resources = () => {
</
div
>
</
div
>
</
section
>
</
section
>
);
);
};
}
)
;
export
default
Resources
;
export
default
Resources
;
web/src/store/v1/index.ts
View file @
785c250f
export
*
from
"./memo"
;
export
*
from
"./memoFilter"
;
export
*
from
"./memoFilter"
;
web/src/store/v1/memo.ts
deleted
100644 → 0
View file @
dcd68bc5
import
{
uniqueId
}
from
"lodash-es"
;
import
{
create
}
from
"zustand"
;
import
{
combine
}
from
"zustand/middleware"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
CreateMemoRequest
,
ListMemosRequest
,
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
interface
State
{
// stateId is used to identify the store instance state.
// It should be update when any state change.
stateId
:
string
;
memoMapByName
:
Record
<
string
,
Memo
>
;
currentRequest
:
AbortController
|
null
;
}
const
getDefaultState
=
():
State
=>
({
stateId
:
uniqueId
(),
memoMapByName
:
{},
currentRequest
:
null
,
});
export
const
useMemoStore
=
create
(
combine
(
getDefaultState
(),
(
set
,
get
)
=>
({
setState
:
(
state
:
State
)
=>
set
(
state
),
getState
:
()
=>
get
(),
updateStateId
:
()
=>
set
({
stateId
:
uniqueId
()
}),
fetchMemos
:
async
(
request
:
Partial
<
ListMemosRequest
>
)
=>
{
const
currentRequest
=
get
().
currentRequest
;
if
(
currentRequest
)
{
currentRequest
.
abort
();
}
const
controller
=
new
AbortController
();
set
({
currentRequest
:
controller
});
try
{
const
{
memos
,
nextPageToken
}
=
await
memoServiceClient
.
listMemos
(
{
...
request
,
},
{
signal
:
controller
.
signal
},
);
if
(
!
controller
.
signal
.
aborted
)
{
const
memoMap
=
request
.
pageToken
?
{
...
get
().
memoMapByName
}
:
{};
for
(
const
memo
of
memos
)
{
memoMap
[
memo
.
name
]
=
memo
;
}
set
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
});
return
{
memos
,
nextPageToken
};
}
}
catch
(
error
:
any
)
{
if
(
error
.
name
===
"AbortError"
)
{
return
;
}
throw
error
;
}
finally
{
if
(
get
().
currentRequest
===
controller
)
{
set
({
currentRequest
:
null
});
}
}
},
getOrFetchMemoByName
:
async
(
name
:
string
,
options
?:
{
skipCache
?:
boolean
;
skipStore
?:
boolean
})
=>
{
const
memoMap
=
get
().
memoMapByName
;
const
memoCache
=
memoMap
[
name
];
if
(
memoCache
&&
!
options
?.
skipCache
)
{
return
memoCache
;
}
const
memo
=
await
memoServiceClient
.
getMemo
({
name
,
});
if
(
!
options
?.
skipStore
)
{
memoMap
[
name
]
=
memo
;
set
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
});
}
return
memo
;
},
getMemoByName
:
(
name
:
string
)
=>
{
return
get
().
memoMapByName
[
name
];
},
createMemo
:
async
(
request
:
CreateMemoRequest
)
=>
{
const
memo
=
await
memoServiceClient
.
createMemo
(
request
);
const
memoMap
=
get
().
memoMapByName
;
memoMap
[
memo
.
name
]
=
memo
;
set
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
});
return
memo
;
},
updateMemo
:
async
(
update
:
Partial
<
Memo
>
,
updateMask
:
string
[])
=>
{
const
memo
=
await
memoServiceClient
.
updateMemo
({
memo
:
update
,
updateMask
,
});
const
memoMap
=
get
().
memoMapByName
;
memoMap
[
memo
.
name
]
=
memo
;
set
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
});
return
memo
;
},
deleteMemo
:
async
(
name
:
string
)
=>
{
await
memoServiceClient
.
deleteMemo
({
name
,
});
const
memoMap
=
get
().
memoMapByName
;
delete
memoMap
[
name
];
set
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
});
},
})),
);
export
const
useMemoList
=
()
=>
{
const
memoStore
=
useMemoStore
();
const
memos
=
Object
.
values
(
memoStore
.
getState
().
memoMapByName
);
const
reset
=
()
=>
{
memoStore
.
updateStateId
();
};
const
size
=
()
=>
{
return
Object
.
keys
(
memoStore
.
getState
().
memoMapByName
).
length
;
};
return
{
value
:
memos
,
reset
,
size
,
};
};
web/src/store/v2/index.ts
View file @
785c250f
import
memoStore
from
"./memo"
;
import
resourceStore
from
"./resource"
;
import
resourceStore
from
"./resource"
;
import
userStore
from
"./user"
;
import
userStore
from
"./user"
;
import
viewStore
from
"./view"
;
import
viewStore
from
"./view"
;
import
workspaceStore
from
"./workspace"
;
import
workspaceStore
from
"./workspace"
;
export
{
resourceStore
,
workspaceStore
,
userStore
,
viewStore
};
export
{
memoStore
,
resourceStore
,
workspaceStore
,
userStore
,
viewStore
};
web/src/store/v2/memo.ts
0 → 100644
View file @
785c250f
import
{
uniqueId
}
from
"lodash-es"
;
import
{
makeAutoObservable
}
from
"mobx"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
CreateMemoRequest
,
ListMemosRequest
,
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
class
LocalState
{
stateId
:
string
=
uniqueId
();
memoMapByName
:
Record
<
string
,
Memo
>
=
{};
currentRequest
:
AbortController
|
null
=
null
;
constructor
()
{
makeAutoObservable
(
this
);
}
setPartial
(
partial
:
Partial
<
LocalState
>
)
{
Object
.
assign
(
this
,
partial
);
}
updateStateId
()
{
this
.
stateId
=
uniqueId
();
}
get
memos
()
{
return
Object
.
values
(
this
.
memoMapByName
);
}
get
size
()
{
return
Object
.
keys
(
this
.
memoMapByName
).
length
;
}
}
const
memoStore
=
(()
=>
{
const
state
=
new
LocalState
();
const
fetchMemos
=
async
(
request
:
Partial
<
ListMemosRequest
>
)
=>
{
if
(
state
.
currentRequest
)
{
state
.
currentRequest
.
abort
();
}
const
controller
=
new
AbortController
();
state
.
setPartial
({
currentRequest
:
controller
});
try
{
const
{
memos
,
nextPageToken
}
=
await
memoServiceClient
.
listMemos
(
{
...
request
,
},
{
signal
:
controller
.
signal
},
);
if
(
!
controller
.
signal
.
aborted
)
{
const
memoMap
=
request
.
pageToken
?
{
...
state
.
memoMapByName
}
:
{};
for
(
const
memo
of
memos
)
{
memoMap
[
memo
.
name
]
=
memo
;
}
state
.
setPartial
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
,
});
return
{
memos
,
nextPageToken
};
}
}
catch
(
error
:
any
)
{
if
(
error
.
name
===
"AbortError"
)
{
return
;
}
throw
error
;
}
finally
{
if
(
state
.
currentRequest
===
controller
)
{
state
.
setPartial
({
currentRequest
:
null
});
}
}
};
const
getOrFetchMemoByName
=
async
(
name
:
string
,
options
?:
{
skipCache
?:
boolean
;
skipStore
?:
boolean
})
=>
{
const
memoCache
=
state
.
memoMapByName
[
name
];
if
(
memoCache
&&
!
options
?.
skipCache
)
{
return
memoCache
;
}
const
memo
=
await
memoServiceClient
.
getMemo
({
name
,
});
if
(
!
options
?.
skipStore
)
{
const
memoMap
=
{
...
state
.
memoMapByName
};
memoMap
[
name
]
=
memo
;
state
.
setPartial
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
,
});
}
return
memo
;
};
const
getMemoByName
=
(
name
:
string
)
=>
{
return
state
.
memoMapByName
[
name
];
};
const
createMemo
=
async
(
request
:
CreateMemoRequest
)
=>
{
const
memo
=
await
memoServiceClient
.
createMemo
(
request
);
const
memoMap
=
{
...
state
.
memoMapByName
};
memoMap
[
memo
.
name
]
=
memo
;
state
.
setPartial
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
,
});
return
memo
;
};
const
updateMemo
=
async
(
update
:
Partial
<
Memo
>
,
updateMask
:
string
[])
=>
{
const
memo
=
await
memoServiceClient
.
updateMemo
({
memo
:
update
,
updateMask
,
});
const
memoMap
=
{
...
state
.
memoMapByName
};
memoMap
[
memo
.
name
]
=
memo
;
state
.
setPartial
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
,
});
return
memo
;
};
const
deleteMemo
=
async
(
name
:
string
)
=>
{
await
memoServiceClient
.
deleteMemo
({
name
,
});
const
memoMap
=
{
...
state
.
memoMapByName
};
delete
memoMap
[
name
];
state
.
setPartial
({
stateId
:
uniqueId
(),
memoMapByName
:
memoMap
,
});
};
return
{
state
,
fetchMemos
,
getOrFetchMemoByName
,
getMemoByName
,
createMemo
,
updateMemo
,
deleteMemo
,
};
})();
export
default
memoStore
;
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