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
eefce6ad
Commit
eefce6ad
authored
Dec 23, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: implement webhook dispatch in v2 api
parent
c6ebb555
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
296 additions
and
147 deletions
+296
-147
memo_relation_service.go
api/v2/memo_relation_service.go
+91
-0
memo_resource_service.go
api/v2/memo_resource_service.go
+66
-0
memo_service.go
api/v2/memo_service.go
+117
-133
version.go
server/version/version.go
+1
-1
index.tsx
web/src/components/MemoEditor/index.tsx
+20
-6
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+1
-7
No files found.
api/v2/memo_relation_service.go
0 → 100644
View file @
eefce6ad
package
v2
import
(
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/store"
)
func
(
s
*
APIV2Service
)
SetMemoRelations
(
ctx
context
.
Context
,
request
*
apiv2pb
.
SetMemoRelationsRequest
)
(
*
apiv2pb
.
SetMemoRelationsResponse
,
error
)
{
referenceType
:=
store
.
MemoRelationReference
// Delete all reference relations first.
if
err
:=
s
.
Store
.
DeleteMemoRelation
(
ctx
,
&
store
.
DeleteMemoRelation
{
MemoID
:
&
request
.
Id
,
Type
:
&
referenceType
,
});
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to delete memo relation"
)
}
for
_
,
relation
:=
range
request
.
Relations
{
if
_
,
err
:=
s
.
Store
.
UpsertMemoRelation
(
ctx
,
&
store
.
MemoRelation
{
MemoID
:
request
.
Id
,
RelatedMemoID
:
relation
.
RelatedMemoId
,
Type
:
convertMemoRelationTypeToStore
(
relation
.
Type
),
});
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to upsert memo relation"
)
}
}
return
&
apiv2pb
.
SetMemoRelationsResponse
{},
nil
}
func
(
s
*
APIV2Service
)
ListMemoRelations
(
ctx
context
.
Context
,
request
*
apiv2pb
.
ListMemoRelationsRequest
)
(
*
apiv2pb
.
ListMemoRelationsResponse
,
error
)
{
relationList
:=
[]
*
apiv2pb
.
MemoRelation
{}
tempList
,
err
:=
s
.
Store
.
ListMemoRelations
(
ctx
,
&
store
.
FindMemoRelation
{
MemoID
:
&
request
.
Id
,
})
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
relation
:=
range
tempList
{
relationList
=
append
(
relationList
,
convertMemoRelationFromStore
(
relation
))
}
tempList
,
err
=
s
.
Store
.
ListMemoRelations
(
ctx
,
&
store
.
FindMemoRelation
{
RelatedMemoID
:
&
request
.
Id
,
})
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
relation
:=
range
tempList
{
relationList
=
append
(
relationList
,
convertMemoRelationFromStore
(
relation
))
}
response
:=
&
apiv2pb
.
ListMemoRelationsResponse
{
Relations
:
relationList
,
}
return
response
,
nil
}
func
convertMemoRelationFromStore
(
memoRelation
*
store
.
MemoRelation
)
*
apiv2pb
.
MemoRelation
{
return
&
apiv2pb
.
MemoRelation
{
MemoId
:
memoRelation
.
MemoID
,
RelatedMemoId
:
memoRelation
.
RelatedMemoID
,
Type
:
convertMemoRelationTypeFromStore
(
memoRelation
.
Type
),
}
}
func
convertMemoRelationTypeFromStore
(
relationType
store
.
MemoRelationType
)
apiv2pb
.
MemoRelation_Type
{
switch
relationType
{
case
store
.
MemoRelationReference
:
return
apiv2pb
.
MemoRelation_REFERENCE
case
store
.
MemoRelationComment
:
return
apiv2pb
.
MemoRelation_COMMENT
default
:
return
apiv2pb
.
MemoRelation_TYPE_UNSPECIFIED
}
}
func
convertMemoRelationTypeToStore
(
relationType
apiv2pb
.
MemoRelation_Type
)
store
.
MemoRelationType
{
switch
relationType
{
case
apiv2pb
.
MemoRelation_REFERENCE
:
return
store
.
MemoRelationReference
case
apiv2pb
.
MemoRelation_COMMENT
:
return
store
.
MemoRelationComment
default
:
return
store
.
MemoRelationReference
}
}
api/v2/memo_resource_service.go
0 → 100644
View file @
eefce6ad
package
v2
import
(
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/store"
)
func
(
s
*
APIV2Service
)
SetMemoResources
(
ctx
context
.
Context
,
request
*
apiv2pb
.
SetMemoResourcesRequest
)
(
*
apiv2pb
.
SetMemoResourcesResponse
,
error
)
{
resources
,
err
:=
s
.
Store
.
ListResources
(
ctx
,
&
store
.
FindResource
{
MemoID
:
&
request
.
Id
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to list resources"
)
}
// Delete resources that are not in the request.
for
_
,
resource
:=
range
resources
{
found
:=
false
for
_
,
requestResource
:=
range
request
.
Resources
{
if
resource
.
ID
==
int32
(
requestResource
.
Id
)
{
found
=
true
break
}
}
if
!
found
{
if
err
=
s
.
Store
.
DeleteResource
(
ctx
,
&
store
.
DeleteResource
{
ID
:
int32
(
resource
.
ID
),
MemoID
:
&
request
.
Id
,
});
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to delete resource"
)
}
}
}
// Update resources' memo_id in the request.
for
_
,
resource
:=
range
request
.
Resources
{
if
_
,
err
:=
s
.
Store
.
UpdateResource
(
ctx
,
&
store
.
UpdateResource
{
ID
:
resource
.
Id
,
MemoID
:
&
request
.
Id
,
});
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to update resource"
)
}
}
return
&
apiv2pb
.
SetMemoResourcesResponse
{},
nil
}
func
(
s
*
APIV2Service
)
ListMemoResources
(
ctx
context
.
Context
,
request
*
apiv2pb
.
ListMemoResourcesRequest
)
(
*
apiv2pb
.
ListMemoResourcesResponse
,
error
)
{
resources
,
err
:=
s
.
Store
.
ListResources
(
ctx
,
&
store
.
FindResource
{
MemoID
:
&
request
.
Id
,
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to list resources"
)
}
response
:=
&
apiv2pb
.
ListMemoResourcesResponse
{
Resources
:
[]
*
apiv2pb
.
Resource
{},
}
for
_
,
resource
:=
range
resources
{
response
.
Resources
=
append
(
response
.
Resources
,
s
.
convertResourceFromStore
(
ctx
,
resource
))
}
return
response
,
nil
}
api/v2/memo_service.go
View file @
eefce6ad
This diff is collapsed.
Click to expand it.
server/version/version.go
View file @
eefce6ad
...
@@ -12,7 +12,7 @@ import (
...
@@ -12,7 +12,7 @@ import (
var
Version
=
"0.18.1"
var
Version
=
"0.18.1"
// DevVersion is the service current development version.
// DevVersion is the service current development version.
var
DevVersion
=
"0.18.
1
"
var
DevVersion
=
"0.18.
2
"
func
GetCurrentVersion
(
mode
string
)
string
{
func
GetCurrentVersion
(
mode
string
)
string
{
if
mode
==
"dev"
||
mode
==
"demo"
{
if
mode
==
"dev"
||
mode
==
"demo"
{
...
...
web/src/components/MemoEditor/index.tsx
View file @
eefce6ad
...
@@ -9,7 +9,7 @@ import { TAB_SPACE_WIDTH, UNKNOWN_ID } from "@/helpers/consts";
...
@@ -9,7 +9,7 @@ import { TAB_SPACE_WIDTH, UNKNOWN_ID } from "@/helpers/consts";
import
{
useGlobalStore
,
useResourceStore
}
from
"@/store/module"
;
import
{
useGlobalStore
,
useResourceStore
}
from
"@/store/module"
;
import
{
useMemoStore
,
useUserStore
}
from
"@/store/v1"
;
import
{
useMemoStore
,
useUserStore
}
from
"@/store/v1"
;
import
{
MemoRelation
,
MemoRelation_Type
}
from
"@/types/proto/api/v2/memo_relation_service"
;
import
{
MemoRelation
,
MemoRelation_Type
}
from
"@/types/proto/api/v2/memo_relation_service"
;
import
{
Visibility
}
from
"@/types/proto/api/v2/memo_service"
;
import
{
Memo
,
Visibility
}
from
"@/types/proto/api/v2/memo_service"
;
import
{
Resource
}
from
"@/types/proto/api/v2/resource_service"
;
import
{
Resource
}
from
"@/types/proto/api/v2/resource_service"
;
import
{
UserSetting
}
from
"@/types/proto/api/v2/user_service"
;
import
{
UserSetting
}
from
"@/types/proto/api/v2/user_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -28,6 +28,7 @@ interface Props {
...
@@ -28,6 +28,7 @@ interface Props {
editorClassName
?:
string
;
editorClassName
?:
string
;
cacheKey
?:
string
;
cacheKey
?:
string
;
memoId
?:
number
;
memoId
?:
number
;
parentMemoId
?:
number
;
relationList
?:
MemoRelation
[];
relationList
?:
MemoRelation
[];
onConfirm
?:
(
memoId
:
number
)
=>
void
;
onConfirm
?:
(
memoId
:
number
)
=>
void
;
}
}
...
@@ -41,7 +42,7 @@ interface State {
...
@@ -41,7 +42,7 @@ interface State {
}
}
const
MemoEditor
=
(
props
:
Props
)
=>
{
const
MemoEditor
=
(
props
:
Props
)
=>
{
const
{
className
,
editorClassName
,
cacheKey
,
memoId
,
onConfirm
}
=
props
;
const
{
className
,
editorClassName
,
cacheKey
,
memoId
,
parentMemoId
,
onConfirm
}
=
props
;
const
{
i18n
}
=
useTranslation
();
const
{
i18n
}
=
useTranslation
();
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
contentCacheKey
=
`memo-editor-
${
cacheKey
}
`
;
const
contentCacheKey
=
`memo-editor-
${
cacheKey
}
`
;
...
@@ -260,6 +261,7 @@ const MemoEditor = (props: Props) => {
...
@@ -260,6 +261,7 @@ const MemoEditor = (props: Props) => {
});
});
const
content
=
editorRef
.
current
?.
getContent
()
??
""
;
const
content
=
editorRef
.
current
?.
getContent
()
??
""
;
try
{
try
{
// Update memo.
if
(
memoId
&&
memoId
!==
UNKNOWN_ID
)
{
if
(
memoId
&&
memoId
!==
UNKNOWN_ID
)
{
const
prevMemo
=
await
memoStore
.
getOrFetchMemoById
(
memoId
??
UNKNOWN_ID
);
const
prevMemo
=
await
memoStore
.
getOrFetchMemoById
(
memoId
??
UNKNOWN_ID
);
if
(
prevMemo
)
{
if
(
prevMemo
)
{
...
@@ -284,10 +286,22 @@ const MemoEditor = (props: Props) => {
...
@@ -284,10 +286,22 @@ const MemoEditor = (props: Props) => {
}
}
}
}
}
else
{
}
else
{
const
memo
=
await
memoStore
.
createMemo
({
// Create memo or memo comment.
content
,
const
request
=
!
parentMemoId
visibility
:
state
.
memoVisibility
,
?
memoStore
.
createMemo
({
});
content
,
visibility
:
state
.
memoVisibility
,
})
:
memoServiceClient
.
createMemoComment
({
id
:
parentMemoId
,
create
:
{
content
,
visibility
:
state
.
memoVisibility
,
},
})
.
then
(({
memo
})
=>
memo
as
Memo
);
const
memo
=
await
request
;
await
memoServiceClient
.
setMemoResources
({
await
memoServiceClient
.
setMemoResources
({
id
:
memo
.
id
,
id
:
memo
.
id
,
resources
:
state
.
resourceList
,
resources
:
state
.
resourceList
,
...
...
web/src/pages/MemoDetail.tsx
View file @
eefce6ad
...
@@ -15,7 +15,6 @@ import MobileHeader from "@/components/MobileHeader";
...
@@ -15,7 +15,6 @@ import MobileHeader from "@/components/MobileHeader";
import
showShareMemoDialog
from
"@/components/ShareMemoDialog"
;
import
showShareMemoDialog
from
"@/components/ShareMemoDialog"
;
import
UserAvatar
from
"@/components/UserAvatar"
;
import
UserAvatar
from
"@/components/UserAvatar"
;
import
VisibilityIcon
from
"@/components/VisibilityIcon"
;
import
VisibilityIcon
from
"@/components/VisibilityIcon"
;
import
{
UNKNOWN_ID
}
from
"@/helpers/consts"
;
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
...
@@ -214,12 +213,7 @@ const MemoDetail = () => {
...
@@ -214,12 +213,7 @@ const MemoDetail = () => {
{
/* Only show comment editor when user login */
}
{
/* Only show comment editor when user login */
}
{
currentUser
&&
(
{
currentUser
&&
(
<
MemoEditor
<
MemoEditor
key=
{
memo
.
id
}
cacheKey=
{
`comment-editor-${memo.id}`
}
parentMemoId=
{
memo
.
id
}
onConfirm=
{
handleCommentCreated
}
/>
key=
{
memo
.
id
}
cacheKey=
{
`comment-editor-${memo.id}`
}
relationList=
{
[{
memoId
:
UNKNOWN_ID
,
relatedMemoId
:
memo
.
id
,
type
:
MemoRelation_Type
.
COMMENT
}]
}
onConfirm=
{
handleCommentCreated
}
/>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
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