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
3dddd3ec
Commit
3dddd3ec
authored
Feb 09, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: tweak reaction store
parent
81aa9b10
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
210 additions
and
67 deletions
+210
-67
apidocs.swagger.yaml
api/v2/apidocs.swagger.yaml
+2
-0
reaction_service.proto
proto/api/v2/reaction_service.proto
+1
-0
README.md
proto/gen/api/v2/README.md
+1
-0
reaction_service.pb.go
proto/gen/api/v2/reaction_service.pb.go
+19
-15
README.md
proto/gen/store/README.md
+1
-0
reaction.pb.go
proto/gen/store/reaction.pb.go
+17
-13
reaction.proto
proto/store/reaction.proto
+1
-0
version.go
server/version/version.go
+2
-2
LATEST__SCHEMA.sql
store/db/mysql/migration/dev/LATEST__SCHEMA.sql
+10
-0
00__reaction.sql
store/db/mysql/migration/prod/0.20/00__reaction.sql
+9
-0
LATEST__SCHEMA.sql
store/db/mysql/migration/prod/LATEST__SCHEMA.sql
+10
-0
reaction.go
store/db/mysql/reaction.go
+30
-7
LATEST__SCHEMA.sql
store/db/postgres/migration/dev/LATEST__SCHEMA.sql
+10
-0
00_reaction.sql
store/db/postgres/migration/prod/0.20/00_reaction.sql
+9
-0
LATEST__SCHEMA.sql
store/db/postgres/migration/prod/LATEST__SCHEMA.sql
+10
-0
LATEST__SCHEMA.sql
store/db/sqlite/migration/dev/LATEST__SCHEMA.sql
+1
-0
00__reaction.sql
store/db/sqlite/migration/prod/0.20/00__reaction.sql
+9
-0
LATEST__SCHEMA.sql
store/db/sqlite/migration/prod/LATEST__SCHEMA.sql
+10
-0
store.go
test/store/store.go
+4
-2
MemoActionMenu.tsx
web/src/components/MemoActionMenu.tsx
+1
-1
MemoView.tsx
web/src/components/MemoView.tsx
+8
-10
ReactionSelector.tsx
web/src/components/ReactionSelector.tsx
+37
-11
ReactionView.tsx
web/src/components/ReactionView.tsx
+8
-6
No files found.
api/v2/apidocs.swagger.yaml
View file @
3dddd3ec
...
@@ -427,6 +427,7 @@ paths:
...
@@ -427,6 +427,7 @@ paths:
-
EYES
-
EYES
-
THINKING_FACE
-
THINKING_FACE
-
CLOWN_FACE
-
CLOWN_FACE
-
QUESTION_MARK
default
:
TYPE_UNSPECIFIED
default
:
TYPE_UNSPECIFIED
tags
:
tags
:
-
MemoService
-
MemoService
...
@@ -1557,6 +1558,7 @@ definitions:
...
@@ -1557,6 +1558,7 @@ definitions:
-
EYES
-
EYES
-
THINKING_FACE
-
THINKING_FACE
-
CLOWN_FACE
-
CLOWN_FACE
-
QUESTION_MARK
default
:
TYPE_UNSPECIFIED
default
:
TYPE_UNSPECIFIED
apiv2RowStatus
:
apiv2RowStatus
:
type
:
string
type
:
string
...
...
proto/api/v2/reaction_service.proto
View file @
3dddd3ec
...
@@ -24,6 +24,7 @@ message Reaction {
...
@@ -24,6 +24,7 @@ message Reaction {
EYES
=
9
;
EYES
=
9
;
THINKING_FACE
=
10
;
THINKING_FACE
=
10
;
CLOWN_FACE
=
11
;
CLOWN_FACE
=
11
;
QUESTION_MARK
=
12
;
}
}
Type
reaction_type
=
4
;
Type
reaction_type
=
4
;
}
}
proto/gen/api/v2/README.md
View file @
3dddd3ec
...
@@ -1182,6 +1182,7 @@ Used internally for obfuscating the page token.
...
@@ -1182,6 +1182,7 @@ Used internally for obfuscating the page token.
| EYES | 9 | |
| EYES | 9 | |
| THINKING_FACE | 10 | |
| THINKING_FACE | 10 | |
| CLOWN_FACE | 11 | |
| CLOWN_FACE | 11 | |
| QUESTION_MARK | 12 | |
...
...
proto/gen/api/v2/reaction_service.pb.go
View file @
3dddd3ec
...
@@ -35,6 +35,7 @@ const (
...
@@ -35,6 +35,7 @@ const (
Reaction_EYES
Reaction_Type
=
9
Reaction_EYES
Reaction_Type
=
9
Reaction_THINKING_FACE
Reaction_Type
=
10
Reaction_THINKING_FACE
Reaction_Type
=
10
Reaction_CLOWN_FACE
Reaction_Type
=
11
Reaction_CLOWN_FACE
Reaction_Type
=
11
Reaction_QUESTION_MARK
Reaction_Type
=
12
)
)
// Enum value maps for Reaction_Type.
// Enum value maps for Reaction_Type.
...
@@ -52,6 +53,7 @@ var (
...
@@ -52,6 +53,7 @@ var (
9
:
"EYES"
,
9
:
"EYES"
,
10
:
"THINKING_FACE"
,
10
:
"THINKING_FACE"
,
11
:
"CLOWN_FACE"
,
11
:
"CLOWN_FACE"
,
12
:
"QUESTION_MARK"
,
}
}
Reaction_Type_value
=
map
[
string
]
int32
{
Reaction_Type_value
=
map
[
string
]
int32
{
"TYPE_UNSPECIFIED"
:
0
,
"TYPE_UNSPECIFIED"
:
0
,
...
@@ -66,6 +68,7 @@ var (
...
@@ -66,6 +68,7 @@ var (
"EYES"
:
9
,
"EYES"
:
9
,
"THINKING_FACE"
:
10
,
"THINKING_FACE"
:
10
,
"CLOWN_FACE"
:
11
,
"CLOWN_FACE"
:
11
,
"QUESTION_MARK"
:
12
,
}
}
)
)
...
@@ -172,7 +175,7 @@ var File_api_v2_reaction_service_proto protoreflect.FileDescriptor
...
@@ -172,7 +175,7 @@ var File_api_v2_reaction_service_proto protoreflect.FileDescriptor
var
file_api_v2_reaction_service_proto_rawDesc
=
[]
byte
{
var
file_api_v2_reaction_service_proto_rawDesc
=
[]
byte
{
0x0a
,
0x1d
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x0a
,
0x1d
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x5f
,
0x73
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x12
,
0x6e
,
0x5f
,
0x73
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x12
,
0x0c
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x22
,
0x
ce
,
0x02
,
0x0c
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x22
,
0x
e1
,
0x02
,
0x0a
,
0x08
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x0a
,
0x08
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x18
,
0x0a
,
0x07
,
0x63
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x18
,
0x0a
,
0x07
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x6f
,
0x72
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x07
,
0x63
,
0x72
,
0x65
,
0x65
,
0x61
,
0x74
,
0x6f
,
0x72
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x07
,
0x63
,
0x72
,
0x65
,
...
@@ -182,7 +185,7 @@ var file_api_v2_reaction_service_proto_rawDesc = []byte{
...
@@ -182,7 +185,7 @@ var file_api_v2_reaction_service_proto_rawDesc = []byte{
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x04
,
0x20
,
0x01
,
0x28
,
0x0e
,
0x32
,
0x1b
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x04
,
0x20
,
0x01
,
0x28
,
0x0e
,
0x32
,
0x1b
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x2e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x52
,
0x0c
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6f
,
0x6e
,
0x2e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x52
,
0x0c
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x22
,
0x
b6
,
0x01
,
0x0a
,
0x04
,
0x54
,
0x79
,
0x70
,
0x65
,
0x12
,
0x14
,
0x6e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x22
,
0x
c9
,
0x01
,
0x0a
,
0x04
,
0x54
,
0x79
,
0x70
,
0x65
,
0x12
,
0x14
,
0x0a
,
0x10
,
0x54
,
0x59
,
0x50
,
0x45
,
0x5f
,
0x55
,
0x4e
,
0x53
,
0x50
,
0x45
,
0x43
,
0x49
,
0x46
,
0x49
,
0x0a
,
0x10
,
0x54
,
0x59
,
0x50
,
0x45
,
0x5f
,
0x55
,
0x4e
,
0x53
,
0x50
,
0x45
,
0x43
,
0x49
,
0x46
,
0x49
,
0x45
,
0x44
,
0x10
,
0x00
,
0x12
,
0x0d
,
0x0a
,
0x09
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x55
,
0x45
,
0x44
,
0x10
,
0x00
,
0x12
,
0x0d
,
0x0a
,
0x09
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x55
,
0x50
,
0x10
,
0x01
,
0x12
,
0x0f
,
0x0a
,
0x0b
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x44
,
0x4f
,
0x50
,
0x10
,
0x01
,
0x12
,
0x0f
,
0x0a
,
0x0b
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x44
,
0x4f
,
...
@@ -193,19 +196,20 @@ var file_api_v2_reaction_service_proto_rawDesc = []byte{
...
@@ -193,19 +196,20 @@ var file_api_v2_reaction_service_proto_rawDesc = []byte{
0x41
,
0x4e
,
0x44
,
0x10
,
0x07
,
0x12
,
0x0a
,
0x0a
,
0x06
,
0x52
,
0x4f
,
0x43
,
0x4b
,
0x45
,
0x54
,
0x10
,
0x41
,
0x4e
,
0x44
,
0x10
,
0x07
,
0x12
,
0x0a
,
0x0a
,
0x06
,
0x52
,
0x4f
,
0x43
,
0x4b
,
0x45
,
0x54
,
0x10
,
0x08
,
0x12
,
0x08
,
0x0a
,
0x04
,
0x45
,
0x59
,
0x45
,
0x53
,
0x10
,
0x09
,
0x12
,
0x11
,
0x0a
,
0x0d
,
0x54
,
0x08
,
0x12
,
0x08
,
0x0a
,
0x04
,
0x45
,
0x59
,
0x45
,
0x53
,
0x10
,
0x09
,
0x12
,
0x11
,
0x0a
,
0x0d
,
0x54
,
0x48
,
0x49
,
0x4e
,
0x4b
,
0x49
,
0x4e
,
0x47
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0a
,
0x12
,
0x0e
,
0x48
,
0x49
,
0x4e
,
0x4b
,
0x49
,
0x4e
,
0x47
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0a
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x43
,
0x4c
,
0x4f
,
0x57
,
0x4e
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0b
,
0x42
,
0xac
,
0x0a
,
0x0a
,
0x43
,
0x4c
,
0x4f
,
0x57
,
0x4e
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0b
,
0x12
,
0x11
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x0a
,
0x0d
,
0x51
,
0x55
,
0x45
,
0x53
,
0x54
,
0x49
,
0x4f
,
0x4e
,
0x5f
,
0x4d
,
0x41
,
0x52
,
0x4b
,
0x10
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x14
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x53
,
0x65
,
0x72
,
0x0c
,
0x42
,
0xac
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x67
,
0x69
,
0x74
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x14
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x67
,
0x69
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x3b
,
0x61
,
0x70
,
0x69
,
0x76
,
0x32
,
0xa2
,
0x02
,
0x03
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x70
,
0x69
,
0x2e
,
0x67
,
0x65
,
0x6e
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x3b
,
0x61
,
0x70
,
0x69
,
0x76
,
0x32
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0x70
,
0x69
,
0x2e
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0e
,
0x4d
,
0x69
,
0x5c
,
0x56
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x70
,
0x69
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x5c
,
0x56
,
0x32
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
0x02
,
0x0e
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x70
,
0x69
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
}
}
var
(
var
(
...
...
proto/gen/store/README.md
View file @
3dddd3ec
...
@@ -224,6 +224,7 @@
...
@@ -224,6 +224,7 @@
| EYES | 9 | |
| EYES | 9 | |
| THINKING_FACE | 10 | |
| THINKING_FACE | 10 | |
| CLOWN_FACE | 11 | |
| CLOWN_FACE | 11 | |
| QUESTION_MARK | 12 | |
...
...
proto/gen/store/reaction.pb.go
View file @
3dddd3ec
...
@@ -35,6 +35,7 @@ const (
...
@@ -35,6 +35,7 @@ const (
Reaction_EYES
Reaction_Type
=
9
Reaction_EYES
Reaction_Type
=
9
Reaction_THINKING_FACE
Reaction_Type
=
10
Reaction_THINKING_FACE
Reaction_Type
=
10
Reaction_CLOWN_FACE
Reaction_Type
=
11
Reaction_CLOWN_FACE
Reaction_Type
=
11
Reaction_QUESTION_MARK
Reaction_Type
=
12
)
)
// Enum value maps for Reaction_Type.
// Enum value maps for Reaction_Type.
...
@@ -52,6 +53,7 @@ var (
...
@@ -52,6 +53,7 @@ var (
9
:
"EYES"
,
9
:
"EYES"
,
10
:
"THINKING_FACE"
,
10
:
"THINKING_FACE"
,
11
:
"CLOWN_FACE"
,
11
:
"CLOWN_FACE"
,
12
:
"QUESTION_MARK"
,
}
}
Reaction_Type_value
=
map
[
string
]
int32
{
Reaction_Type_value
=
map
[
string
]
int32
{
"TYPE_UNSPECIFIED"
:
0
,
"TYPE_UNSPECIFIED"
:
0
,
...
@@ -66,6 +68,7 @@ var (
...
@@ -66,6 +68,7 @@ var (
"EYES"
:
9
,
"EYES"
:
9
,
"THINKING_FACE"
:
10
,
"THINKING_FACE"
:
10
,
"CLOWN_FACE"
:
11
,
"CLOWN_FACE"
:
11
,
"QUESTION_MARK"
:
12
,
}
}
)
)
...
@@ -182,7 +185,7 @@ var File_store_reaction_proto protoreflect.FileDescriptor
...
@@ -182,7 +185,7 @@ var File_store_reaction_proto protoreflect.FileDescriptor
var
file_store_reaction_proto_rawDesc
=
[]
byte
{
var
file_store_reaction_proto_rawDesc
=
[]
byte
{
0x0a
,
0x14
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x2f
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x0a
,
0x14
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x2f
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x12
,
0x0b
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x12
,
0x0b
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x22
,
0x
f1
,
0x02
,
0x0a
,
0x08
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x6f
,
0x72
,
0x65
,
0x22
,
0x
84
,
0x03
,
0x0a
,
0x08
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x1d
,
0x0a
,
0x0a
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x74
,
0x73
,
0x18
,
0x02
,
0x12
,
0x1d
,
0x0a
,
0x0a
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x74
,
0x73
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x03
,
0x52
,
0x09
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x65
,
0x64
,
0x54
,
0x73
,
0x12
,
0x20
,
0x01
,
0x28
,
0x03
,
0x52
,
0x09
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x65
,
0x64
,
0x54
,
0x73
,
0x12
,
...
@@ -193,7 +196,7 @@ var file_store_reaction_proto_rawDesc = []byte{
...
@@ -193,7 +196,7 @@ var file_store_reaction_proto_rawDesc = []byte{
0x0d
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x5f
,
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x05
,
0x0d
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x5f
,
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x05
,
0x20
,
0x01
,
0x28
,
0x0e
,
0x32
,
0x1a
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x6f
,
0x20
,
0x01
,
0x28
,
0x0e
,
0x32
,
0x1a
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x2e
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x2e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x72
,
0x65
,
0x2e
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x2e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x52
,
0x0c
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x22
,
0x
b6
,
0x52
,
0x0c
,
0x72
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x54
,
0x79
,
0x70
,
0x65
,
0x22
,
0x
c9
,
0x01
,
0x0a
,
0x04
,
0x54
,
0x79
,
0x70
,
0x65
,
0x12
,
0x14
,
0x0a
,
0x10
,
0x54
,
0x59
,
0x50
,
0x45
,
0x5f
,
0x01
,
0x0a
,
0x04
,
0x54
,
0x79
,
0x70
,
0x65
,
0x12
,
0x14
,
0x0a
,
0x10
,
0x54
,
0x59
,
0x50
,
0x45
,
0x5f
,
0x55
,
0x4e
,
0x53
,
0x50
,
0x45
,
0x43
,
0x49
,
0x46
,
0x49
,
0x45
,
0x44
,
0x10
,
0x00
,
0x12
,
0x0d
,
0x0a
,
0x55
,
0x4e
,
0x53
,
0x50
,
0x45
,
0x43
,
0x49
,
0x46
,
0x49
,
0x45
,
0x44
,
0x10
,
0x00
,
0x12
,
0x0d
,
0x0a
,
0x09
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x55
,
0x50
,
0x10
,
0x01
,
0x12
,
0x0f
,
0x0a
,
0x0b
,
0x09
,
0x54
,
0x48
,
0x55
,
0x4d
,
0x42
,
0x53
,
0x5f
,
0x55
,
0x50
,
0x10
,
0x01
,
0x12
,
0x0f
,
0x0a
,
0x0b
,
...
@@ -205,17 +208,18 @@ var file_store_reaction_proto_rawDesc = []byte{
...
@@ -205,17 +208,18 @@ var file_store_reaction_proto_rawDesc = []byte{
0x0a
,
0x06
,
0x52
,
0x4f
,
0x43
,
0x4b
,
0x45
,
0x54
,
0x10
,
0x08
,
0x12
,
0x08
,
0x0a
,
0x04
,
0x45
,
0x59
,
0x0a
,
0x06
,
0x52
,
0x4f
,
0x43
,
0x4b
,
0x45
,
0x54
,
0x10
,
0x08
,
0x12
,
0x08
,
0x0a
,
0x04
,
0x45
,
0x59
,
0x45
,
0x53
,
0x10
,
0x09
,
0x12
,
0x11
,
0x0a
,
0x0d
,
0x54
,
0x48
,
0x49
,
0x4e
,
0x4b
,
0x49
,
0x4e
,
0x47
,
0x45
,
0x53
,
0x10
,
0x09
,
0x12
,
0x11
,
0x0a
,
0x0d
,
0x54
,
0x48
,
0x49
,
0x4e
,
0x4b
,
0x49
,
0x4e
,
0x47
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0a
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x43
,
0x4c
,
0x4f
,
0x57
,
0x4e
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0a
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x43
,
0x4c
,
0x4f
,
0x57
,
0x4e
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0b
,
0x42
,
0x98
,
0x01
,
0x0a
,
0x0f
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x5f
,
0x46
,
0x41
,
0x43
,
0x45
,
0x10
,
0x0b
,
0x12
,
0x11
,
0x0a
,
0x0d
,
0x51
,
0x55
,
0x45
,
0x53
,
0x54
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x42
,
0x0d
,
0x52
,
0x65
,
0x61
,
0x49
,
0x4f
,
0x4e
,
0x5f
,
0x4d
,
0x41
,
0x52
,
0x4b
,
0x10
,
0x0c
,
0x42
,
0x98
,
0x01
,
0x0a
,
0x0f
,
0x63
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x29
,
0x67
,
0x69
,
0x6f
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x42
,
0x0d
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x52
,
0x65
,
0x61
,
0x63
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x29
,
0x67
,
0x69
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x6e
,
0x2f
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x53
,
0x58
,
0xaa
,
0x02
,
0x0b
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xca
,
0x02
,
0x0b
,
0x4d
,
0x65
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x2f
,
0x73
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x53
,
0x58
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xe2
,
0x02
,
0x17
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0xaa
,
0x02
,
0x0b
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xca
,
0x02
,
0x73
,
0x5c
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x0b
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0xe2
,
0x02
,
0x17
,
0x4d
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x53
,
0x74
,
0x6f
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x72
,
0x65
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
0x74
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x53
,
0x74
,
0x6f
,
0x72
,
0x65
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
}
}
var
(
var
(
...
...
proto/store/reaction.proto
View file @
3dddd3ec
...
@@ -28,6 +28,7 @@ message Reaction {
...
@@ -28,6 +28,7 @@ message Reaction {
EYES
=
9
;
EYES
=
9
;
THINKING_FACE
=
10
;
THINKING_FACE
=
10
;
CLOWN_FACE
=
11
;
CLOWN_FACE
=
11
;
QUESTION_MARK
=
12
;
}
}
Type
reaction_type
=
5
;
Type
reaction_type
=
5
;
}
}
server/version/version.go
View file @
3dddd3ec
...
@@ -9,10 +9,10 @@ import (
...
@@ -9,10 +9,10 @@ import (
// Version is the service current released version.
// Version is the service current released version.
// Semantic versioning: https://semver.org/
// Semantic versioning: https://semver.org/
var
Version
=
"0.
19.1
"
var
Version
=
"0.
20.0
"
// DevVersion is the service current development version.
// DevVersion is the service current development version.
var
DevVersion
=
"0.
19.1
"
var
DevVersion
=
"0.
20.0
"
func
GetCurrentVersion
(
mode
string
)
string
{
func
GetCurrentVersion
(
mode
string
)
string
{
if
mode
==
"dev"
||
mode
==
"demo"
{
if
mode
==
"dev"
||
mode
==
"demo"
{
...
...
store/db/mysql/migration/dev/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -131,3 +131,13 @@ CREATE TABLE `webhook` (
...
@@ -131,3 +131,13 @@ CREATE TABLE `webhook` (
`name`
TEXT
NOT
NULL
,
`name`
TEXT
NOT
NULL
,
`url`
TEXT
NOT
NULL
`url`
TEXT
NOT
NULL
);
);
-- reaction
CREATE
TABLE
`reaction`
(
`id`
INT
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
`created_ts`
TIMESTAMP
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
,
`creator_id`
INT
NOT
NULL
,
`content_id`
VARCHAR
(
256
)
NOT
NULL
,
`reaction_type`
VARCHAR
(
256
)
NOT
NULL
,
UNIQUE
(
`creator_id`
,
`content_id`
,
`reaction_type`
)
);
store/db/mysql/migration/prod/0.20/00__reaction.sql
0 → 100644
View file @
3dddd3ec
-- reaction
CREATE
TABLE
`reaction`
(
`id`
INT
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
`created_ts`
TIMESTAMP
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
,
`creator_id`
INT
NOT
NULL
,
`content_id`
VARCHAR
(
256
)
NOT
NULL
,
`reaction_type`
VARCHAR
(
256
)
NOT
NULL
,
UNIQUE
(
`creator_id`
,
`content_id`
,
`reaction_type`
)
);
store/db/mysql/migration/prod/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -131,3 +131,13 @@ CREATE TABLE `webhook` (
...
@@ -131,3 +131,13 @@ CREATE TABLE `webhook` (
`name`
TEXT
NOT
NULL
,
`name`
TEXT
NOT
NULL
,
`url`
TEXT
NOT
NULL
`url`
TEXT
NOT
NULL
);
);
-- reaction
CREATE
TABLE
`reaction`
(
`id`
INT
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
`created_ts`
TIMESTAMP
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
,
`creator_id`
INT
NOT
NULL
,
`content_id`
VARCHAR
(
256
)
NOT
NULL
,
`reaction_type`
VARCHAR
(
256
)
NOT
NULL
,
UNIQUE
(
`creator_id`
,
`content_id`
,
`reaction_type`
)
);
store/db/mysql/reaction.go
View file @
3dddd3ec
...
@@ -4,6 +4,7 @@ import (
...
@@ -4,6 +4,7 @@ import (
"context"
"context"
"strings"
"strings"
"github.com/pkg/errors"
storepb
"github.com/usememos/memos/proto/gen/store"
storepb
"github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/store"
"github.com/usememos/memos/store"
)
)
...
@@ -12,15 +13,24 @@ func (d *DB) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*sto
...
@@ -12,15 +13,24 @@ func (d *DB) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*sto
fields
:=
[]
string
{
"`creator_id`"
,
"`content_id`"
,
"`reaction_type`"
}
fields
:=
[]
string
{
"`creator_id`"
,
"`content_id`"
,
"`reaction_type`"
}
placeholder
:=
[]
string
{
"?"
,
"?"
,
"?"
}
placeholder
:=
[]
string
{
"?"
,
"?"
,
"?"
}
args
:=
[]
interface
{}{
upsert
.
CreatorId
,
upsert
.
ContentId
,
upsert
.
ReactionType
.
String
()}
args
:=
[]
interface
{}{
upsert
.
CreatorId
,
upsert
.
ContentId
,
upsert
.
ReactionType
.
String
()}
stmt
:=
"INSERT INTO `reaction` ("
+
strings
.
Join
(
fields
,
", "
)
+
") VALUES ("
+
strings
.
Join
(
placeholder
,
", "
)
+
") RETURNING `id`, `created_ts`"
stmt
:=
"INSERT INTO `reaction` ("
+
strings
.
Join
(
fields
,
", "
)
+
") VALUES ("
+
strings
.
Join
(
placeholder
,
", "
)
+
")"
if
err
:=
d
.
db
.
QueryRowContext
(
ctx
,
stmt
,
args
...
)
.
Scan
(
result
,
err
:=
d
.
db
.
ExecContext
(
ctx
,
stmt
,
args
...
)
&
upsert
.
Id
,
if
err
!=
nil
{
&
upsert
.
CreatedTs
,
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
reaction
:=
upsert
rawID
,
err
:=
result
.
LastInsertId
()
if
err
!=
nil
{
return
nil
,
err
}
id
:=
int32
(
rawID
)
reaction
,
err
:=
d
.
GetReaction
(
ctx
,
&
store
.
FindReaction
{
ID
:
&
id
})
if
err
!=
nil
{
return
nil
,
err
}
if
reaction
==
nil
{
return
nil
,
errors
.
Errorf
(
"failed to create reaction"
)
}
return
reaction
,
nil
return
reaction
,
nil
}
}
...
@@ -39,7 +49,7 @@ func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*st
...
@@ -39,7 +49,7 @@ func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*st
rows
,
err
:=
d
.
db
.
QueryContext
(
ctx
,
`
rows
,
err
:=
d
.
db
.
QueryContext
(
ctx
,
`
SELECT
SELECT
id,
id,
created_ts,
UNIX_TIMESTAMP(created_ts) AS
created_ts,
creator_id,
creator_id,
content_id,
content_id,
reaction_type
reaction_type
...
@@ -77,6 +87,19 @@ func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*st
...
@@ -77,6 +87,19 @@ func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*st
return
list
,
nil
return
list
,
nil
}
}
func
(
d
*
DB
)
GetReaction
(
ctx
context
.
Context
,
find
*
store
.
FindReaction
)
(
*
storepb
.
Reaction
,
error
)
{
list
,
err
:=
d
.
ListReactions
(
ctx
,
find
)
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
list
)
==
0
{
return
nil
,
nil
}
reaction
:=
list
[
0
]
return
reaction
,
nil
}
func
(
d
*
DB
)
DeleteReaction
(
ctx
context
.
Context
,
delete
*
store
.
DeleteReaction
)
error
{
func
(
d
*
DB
)
DeleteReaction
(
ctx
context
.
Context
,
delete
*
store
.
DeleteReaction
)
error
{
_
,
err
:=
d
.
db
.
ExecContext
(
ctx
,
"DELETE FROM `reaction` WHERE `id` = ?"
,
delete
.
ID
)
_
,
err
:=
d
.
db
.
ExecContext
(
ctx
,
"DELETE FROM `reaction` WHERE `id` = ?"
,
delete
.
ID
)
return
err
return
err
...
...
store/db/postgres/migration/dev/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -131,3 +131,13 @@ CREATE TABLE webhook (
...
@@ -131,3 +131,13 @@ CREATE TABLE webhook (
name
TEXT
NOT
NULL
,
name
TEXT
NOT
NULL
,
url
TEXT
NOT
NULL
url
TEXT
NOT
NULL
);
);
-- reaction
CREATE
TABLE
reaction
(
id
SERIAL
PRIMARY
KEY
,
created_ts
BIGINT
NOT
NULL
DEFAULT
EXTRACT
(
EPOCH
FROM
NOW
()),
creator_id
INTEGER
NOT
NULL
,
content_id
TEXT
NOT
NULL
,
reaction_type
TEXT
NOT
NULL
,
UNIQUE
(
creator_id
,
content_id
,
reaction_type
)
);
store/db/postgres/migration/prod/0.20/00_reaction.sql
0 → 100644
View file @
3dddd3ec
-- reaction
CREATE
TABLE
reaction
(
id
SERIAL
PRIMARY
KEY
,
created_ts
BIGINT
NOT
NULL
DEFAULT
EXTRACT
(
EPOCH
FROM
NOW
()),
creator_id
INTEGER
NOT
NULL
,
content_id
TEXT
NOT
NULL
,
reaction_type
TEXT
NOT
NULL
,
UNIQUE
(
creator_id
,
content_id
,
reaction_type
)
);
store/db/postgres/migration/prod/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -131,3 +131,13 @@ CREATE TABLE webhook (
...
@@ -131,3 +131,13 @@ CREATE TABLE webhook (
name
TEXT
NOT
NULL
,
name
TEXT
NOT
NULL
,
url
TEXT
NOT
NULL
url
TEXT
NOT
NULL
);
);
-- reaction
CREATE
TABLE
reaction
(
id
SERIAL
PRIMARY
KEY
,
created_ts
BIGINT
NOT
NULL
DEFAULT
EXTRACT
(
EPOCH
FROM
NOW
()),
creator_id
INTEGER
NOT
NULL
,
content_id
TEXT
NOT
NULL
,
reaction_type
TEXT
NOT
NULL
,
UNIQUE
(
creator_id
,
content_id
,
reaction_type
)
);
store/db/sqlite/migration/dev/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -145,6 +145,7 @@ CREATE TABLE webhook (
...
@@ -145,6 +145,7 @@ CREATE TABLE webhook (
CREATE
INDEX
idx_webhook_creator_id
ON
webhook
(
creator_id
);
CREATE
INDEX
idx_webhook_creator_id
ON
webhook
(
creator_id
);
-- reaction
CREATE
TABLE
reaction
(
CREATE
TABLE
reaction
(
id
INTEGER
PRIMARY
KEY
AUTOINCREMENT
,
id
INTEGER
PRIMARY
KEY
AUTOINCREMENT
,
created_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
created_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
...
...
store/db/sqlite/migration/prod/0.20/00__reaction.sql
0 → 100644
View file @
3dddd3ec
-- reaction
CREATE
TABLE
reaction
(
id
INTEGER
PRIMARY
KEY
AUTOINCREMENT
,
created_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
creator_id
INTEGER
NOT
NULL
,
content_id
TEXT
NOT
NULL
,
reaction_type
TEXT
NOT
NULL
,
UNIQUE
(
creator_id
,
content_id
,
reaction_type
)
);
store/db/sqlite/migration/prod/LATEST__SCHEMA.sql
View file @
3dddd3ec
...
@@ -144,3 +144,13 @@ CREATE TABLE webhook (
...
@@ -144,3 +144,13 @@ CREATE TABLE webhook (
);
);
CREATE
INDEX
idx_webhook_creator_id
ON
webhook
(
creator_id
);
CREATE
INDEX
idx_webhook_creator_id
ON
webhook
(
creator_id
);
-- reaction
CREATE
TABLE
reaction
(
id
INTEGER
PRIMARY
KEY
AUTOINCREMENT
,
created_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
creator_id
INTEGER
NOT
NULL
,
content_id
TEXT
NOT
NULL
,
reaction_type
TEXT
NOT
NULL
,
UNIQUE
(
creator_id
,
content_id
,
reaction_type
)
);
test/store/store.go
View file @
3dddd3ec
...
@@ -45,7 +45,8 @@ func resetTestingDB(ctx context.Context, profile *profile.Profile, dbDriver stor
...
@@ -45,7 +45,8 @@ func resetTestingDB(ctx context.Context, profile *profile.Profile, dbDriver stor
DROP TABLE IF EXISTS storage;
DROP TABLE IF EXISTS storage;
DROP TABLE IF EXISTS idp;
DROP TABLE IF EXISTS idp;
DROP TABLE IF EXISTS inbox;
DROP TABLE IF EXISTS inbox;
DROP TABLE IF EXISTS webhook;`
)
DROP TABLE IF EXISTS webhook;
DROP TABLE IF EXISTS reaction;`
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
"failed to reset testing db, error: %+v
\n
"
,
err
)
fmt
.
Printf
(
"failed to reset testing db, error: %+v
\n
"
,
err
)
panic
(
err
)
panic
(
err
)
...
@@ -65,7 +66,8 @@ func resetTestingDB(ctx context.Context, profile *profile.Profile, dbDriver stor
...
@@ -65,7 +66,8 @@ func resetTestingDB(ctx context.Context, profile *profile.Profile, dbDriver stor
DROP TABLE IF EXISTS storage CASCADE;
DROP TABLE IF EXISTS storage CASCADE;
DROP TABLE IF EXISTS idp CASCADE;
DROP TABLE IF EXISTS idp CASCADE;
DROP TABLE IF EXISTS inbox CASCADE;
DROP TABLE IF EXISTS inbox CASCADE;
DROP TABLE IF EXISTS webhook CASCADE;`
)
DROP TABLE IF EXISTS webhook CASCADE;
DROP TABLE IF EXISTS reaction CASCADE;`
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
"failed to reset testing db, error: %+v
\n
"
,
err
)
fmt
.
Printf
(
"failed to reset testing db, error: %+v
\n
"
,
err
)
panic
(
err
)
panic
(
err
)
...
...
web/src/components/MemoActionMenu.tsx
View file @
3dddd3ec
...
@@ -116,7 +116,7 @@ const MemoActionMenu = (props: Props) => {
...
@@ -116,7 +116,7 @@ const MemoActionMenu = (props: Props) => {
</
MenuItem
>
</
MenuItem
>
<
Divider
className=
"!my-1"
/>
<
Divider
className=
"!my-1"
/>
<
div
className=
"-mt-0.5 pl-2 pr-2 text-xs text-gray-400"
>
<
div
className=
"-mt-0.5 pl-2 pr-2 text-xs text-gray-400"
>
<
div
className=
"font-mono max-w-20 cursor-pointer truncate"
onClick=
{
handleCopyMemoId
}
>
<
div
className=
"
mt-1
font-mono max-w-20 cursor-pointer truncate"
onClick=
{
handleCopyMemoId
}
>
ID:
{
memo
.
name
}
ID:
{
memo
.
name
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/MemoView.tsx
View file @
3dddd3ec
...
@@ -124,18 +124,16 @@ const MemoView: React.FC<Props> = (props: Props) => {
...
@@ -124,18 +124,16 @@ const MemoView: React.FC<Props> = (props: Props) => {
</>
</>
)
}
)
}
</
div
>
</
div
>
<
div
className=
"flex flex-row justify-end items-center"
>
<
div
className=
"flex flex-row justify-end items-center
select-none
"
>
<
div
className=
"w-auto
hidden group-hover:flex flex-row justify-between items-center gap-1
"
>
<
div
className=
"w-auto
invisible group-hover:visible flex flex-row justify-between items-center
"
>
{
props
.
showVisibility
&&
memo
.
visibility
!==
Visibility
.
PRIVATE
&&
(
{
props
.
showVisibility
&&
memo
.
visibility
!==
Visibility
.
PRIVATE
&&
(
<>
<
Tooltip
title=
{
t
(
`memo.visibility.${convertVisibilityToString(memo.visibility).toLowerCase()}`
as
any
)
}
placement=
"top"
>
<
Tooltip
title=
{
t
(
`memo.visibility.${convertVisibilityToString(memo.visibility).toLowerCase()}`
as
any
)
}
placement=
"top"
>
<
span
className=
"h-7 w-7 flex justify-center items-center hover:opacity-70"
>
<
span
className=
"h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70"
>
<
VisibilityIcon
visibility=
{
memo
.
visibility
}
/>
<
VisibilityIcon
visibility=
{
memo
.
visibility
}
/>
</
span
>
</
span
>
</
Tooltip
>
</
Tooltip
>
</>
)
}
)
}
{
currentUser
&&
memo
.
reactions
.
length
===
0
&&
<
ReactionSelector
memo=
{
memo
}
/>
}
{
currentUser
&&
<
ReactionSelector
className=
"border-none"
memo=
{
memo
}
/>
}
</
div
>
</
div
>
{
!
readonly
&&
<
MemoActionMenu
memo=
{
memo
}
showPinned=
{
props
.
showPinned
}
/>
}
{
!
readonly
&&
<
MemoActionMenu
memo=
{
memo
}
showPinned=
{
props
.
showPinned
}
/>
}
</
div
>
</
div
>
...
...
web/src/components/ReactionSelector.tsx
View file @
3dddd3ec
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
classNames
from
"classnames"
;
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
Icon
from
"@/components/Icon"
;
import
Icon
from
"@/components/Icon"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
MemoNamePrefix
,
useMemoStore
}
from
"@/store/v1"
;
import
{
MemoNamePrefix
,
useMemoStore
}
from
"@/store/v1"
;
import
{
Memo
}
from
"@/types/proto/api/v2/memo_service"
;
import
{
Memo
}
from
"@/types/proto/api/v2/memo_service"
;
import
{
Reaction_Type
}
from
"@/types/proto/api/v2/reaction_service"
;
import
{
Reaction_Type
}
from
"@/types/proto/api/v2/reaction_service"
;
...
@@ -10,6 +12,7 @@ import { stringifyReactionType } from "./ReactionView";
...
@@ -10,6 +12,7 @@ import { stringifyReactionType } from "./ReactionView";
interface
Props
{
interface
Props
{
memo
:
Memo
;
memo
:
Memo
;
className
?:
string
;
}
}
const
REACTION_TYPES
=
[
const
REACTION_TYPES
=
[
...
@@ -24,10 +27,12 @@ const REACTION_TYPES = [
...
@@ -24,10 +27,12 @@ const REACTION_TYPES = [
Reaction_Type
.
EYES
,
Reaction_Type
.
EYES
,
Reaction_Type
.
THINKING_FACE
,
Reaction_Type
.
THINKING_FACE
,
Reaction_Type
.
CLOWN_FACE
,
Reaction_Type
.
CLOWN_FACE
,
Reaction_Type
.
QUESTION_MARK
,
];
];
const
ReactionSelector
=
(
props
:
Props
)
=>
{
const
ReactionSelector
=
(
props
:
Props
)
=>
{
const
{
memo
}
=
props
;
const
{
memo
,
className
}
=
props
;
const
currentUser
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
memoStore
=
useMemoStore
();
const
[
open
,
setOpen
]
=
useState
(
false
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
containerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
containerRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
@@ -36,15 +41,28 @@ const ReactionSelector = (props: Props) => {
...
@@ -36,15 +41,28 @@ const ReactionSelector = (props: Props) => {
setOpen
(
false
);
setOpen
(
false
);
});
});
const
handleReactionClick
=
async
(
reaction
:
Reaction_Type
)
=>
{
const
hasReacted
=
(
reactionType
:
Reaction_Type
)
=>
{
return
memo
.
reactions
.
some
((
r
)
=>
r
.
reactionType
===
reactionType
&&
r
.
creator
===
currentUser
?.
name
);
};
const
handleReactionClick
=
async
(
reactionType
:
Reaction_Type
)
=>
{
try
{
try
{
await
memoServiceClient
.
upsertMemoReaction
({
if
(
hasReacted
(
reactionType
))
{
id
:
memo
.
id
,
const
reactions
=
memo
.
reactions
.
filter
(
reaction
:
{
(
reaction
)
=>
reaction
.
reactionType
===
reactionType
&&
reaction
.
creator
===
currentUser
.
name
,
contentId
:
`
${
MemoNamePrefix
}${
memo
.
id
}
`
,
);
reactionType
:
reaction
,
for
(
const
reaction
of
reactions
)
{
},
await
memoServiceClient
.
deleteMemoReaction
({
id
:
reaction
.
id
});
});
}
}
else
{
await
memoServiceClient
.
upsertMemoReaction
({
id
:
memo
.
id
,
reaction
:
{
contentId
:
`
${
MemoNamePrefix
}${
memo
.
id
}
`
,
reactionType
:
reactionType
,
},
});
}
await
memoStore
.
getOrFetchMemoById
(
memo
.
id
,
{
await
memoStore
.
getOrFetchMemoById
(
memo
.
id
,
{
skipCache
:
true
,
skipCache
:
true
,
});
});
...
@@ -57,7 +75,12 @@ const ReactionSelector = (props: Props) => {
...
@@ -57,7 +75,12 @@ const ReactionSelector = (props: Props) => {
return
(
return
(
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
span
className=
"h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70"
>
<
span
className=
{
classNames
(
"h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70"
,
className
,
)
}
>
<
Icon
.
SmilePlus
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
<
Icon
.
SmilePlus
className=
"w-4 h-4 mx-auto text-gray-500 dark:text-gray-400"
/>
</
span
>
</
span
>
</
MenuButton
>
</
MenuButton
>
...
@@ -68,7 +91,10 @@ const ReactionSelector = (props: Props) => {
...
@@ -68,7 +91,10 @@ const ReactionSelector = (props: Props) => {
return
(
return
(
<
span
<
span
key=
{
reactionType
}
key=
{
reactionType
}
className=
"inline-flex w-auto cursor-pointer rounded text-lg px-1 text-gray-500 dark:text-gray-400 hover:bg-zinc-100 dark:hover:bg-zinc-800"
className=
{
classNames
(
"inline-flex w-auto cursor-pointer rounded text-lg px-1 text-gray-500 dark:text-gray-400 hover:opacity-80"
,
hasReacted
(
reactionType
)
&&
"bg-blue-100 dark:bg-zinc-800"
,
)
}
onClick=
{
()
=>
handleReactionClick
(
reactionType
)
}
onClick=
{
()
=>
handleReactionClick
(
reactionType
)
}
>
>
{
stringifyReactionType
(
reactionType
)
}
{
stringifyReactionType
(
reactionType
)
}
...
...
web/src/components/ReactionView.tsx
View file @
3dddd3ec
...
@@ -37,6 +37,8 @@ export const stringifyReactionType = (reactionType: Reaction_Type): string => {
...
@@ -37,6 +37,8 @@ export const stringifyReactionType = (reactionType: Reaction_Type): string => {
return
"🤔"
;
return
"🤔"
;
case
Reaction_Type
.
CLOWN_FACE
:
case
Reaction_Type
.
CLOWN_FACE
:
return
"🤡"
;
return
"🤡"
;
case
Reaction_Type
.
QUESTION_MARK
:
return
"❓"
;
default
:
default
:
return
""
;
return
""
;
}
}
...
@@ -57,16 +59,16 @@ const stringifyUsers = (users: User[]): string => {
...
@@ -57,16 +59,16 @@ const stringifyUsers = (users: User[]): string => {
const
ReactionView
=
(
props
:
Props
)
=>
{
const
ReactionView
=
(
props
:
Props
)
=>
{
const
{
memo
,
reactionType
,
users
}
=
props
;
const
{
memo
,
reactionType
,
users
}
=
props
;
const
currenUser
=
useCurrentUser
();
const
curren
t
User
=
useCurrentUser
();
const
memoStore
=
useMemoStore
();
const
memoStore
=
useMemoStore
();
const
hasReaction
=
users
.
some
((
user
)
=>
curren
User
&&
user
.
username
===
curren
User
.
username
);
const
hasReaction
=
users
.
some
((
user
)
=>
curren
tUser
&&
user
.
username
===
current
User
.
username
);
const
handleReactionClick
=
async
()
=>
{
const
handleReactionClick
=
async
()
=>
{
if
(
!
currenUser
)
{
if
(
!
curren
t
User
)
{
return
;
return
;
}
}
const
index
=
users
.
findIndex
((
user
)
=>
user
.
username
===
currenUser
.
username
);
const
index
=
users
.
findIndex
((
user
)
=>
user
.
username
===
curren
t
User
.
username
);
try
{
try
{
if
(
index
===
-
1
)
{
if
(
index
===
-
1
)
{
await
memoServiceClient
.
upsertMemoReaction
({
await
memoServiceClient
.
upsertMemoReaction
({
...
@@ -78,7 +80,7 @@ const ReactionView = (props: Props) => {
...
@@ -78,7 +80,7 @@ const ReactionView = (props: Props) => {
});
});
}
else
{
}
else
{
const
reactions
=
memo
.
reactions
.
filter
(
const
reactions
=
memo
.
reactions
.
filter
(
(
reaction
)
=>
reaction
.
reactionType
===
reactionType
&&
reaction
.
creator
===
currenUser
.
name
,
(
reaction
)
=>
reaction
.
reactionType
===
reactionType
&&
reaction
.
creator
===
curren
t
User
.
name
,
);
);
for
(
const
reaction
of
reactions
)
{
for
(
const
reaction
of
reactions
)
{
await
memoServiceClient
.
deleteMemoReaction
({
id
:
reaction
.
id
});
await
memoServiceClient
.
deleteMemoReaction
({
id
:
reaction
.
id
});
...
@@ -95,7 +97,7 @@ const ReactionView = (props: Props) => {
...
@@ -95,7 +97,7 @@ const ReactionView = (props: Props) => {
<
div
<
div
className=
{
classNames
(
className=
{
classNames
(
"h-7 border px-2 py-0.5 rounded-full font-memo flex flex-row justify-center items-center gap-1 dark:border-zinc-700"
,
"h-7 border px-2 py-0.5 rounded-full font-memo flex flex-row justify-center items-center gap-1 dark:border-zinc-700"
,
currenUser
&&
"cursor-pointer"
,
curren
t
User
&&
"cursor-pointer"
,
hasReaction
&&
"bg-blue-100 border-blue-200 dark:bg-zinc-900"
,
hasReaction
&&
"bg-blue-100 border-blue-200 dark:bg-zinc-900"
,
)
}
)
}
onClick=
{
handleReactionClick
}
onClick=
{
handleReactionClick
}
...
...
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