chore: exclude comments in memo list response

pull/2716/head
Steven 1 year ago
parent 79c13c6f83
commit a297cc3140

@ -60,7 +60,6 @@ type Memo struct {
Pinned bool `json:"pinned"`
// Related fields
Parent *Memo `json:"parent"`
CreatorName string `json:"creatorName"`
CreatorUsername string `json:"creatorUsername"`
ResourceList []*Resource `json:"resourceList"`
@ -184,11 +183,6 @@ func (s *APIV1Service) GetMemoList(c echo.Context) error {
if rowStatus != "" {
find.RowStatus = &rowStatus
}
pinnedStr := c.QueryParam("pinned")
if pinnedStr != "" {
pinned := pinnedStr == "true"
find.Pinned = &pinned
}
contentSearch := []string{}
tag := c.QueryParam("tag")
@ -867,24 +861,6 @@ func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Mem
relationList = append(relationList, convertMemoRelationFromStore(relation))
}
memoMessage.RelationList = relationList
for _, relation := range memoMessage.RelationList {
if relation.MemoID == memoMessage.ID && relation.Type == MemoRelationComment {
parentMemo, err := s.Store.GetMemo(ctx, &store.FindMemo{
ID: &relation.RelatedMemoID,
})
if err != nil {
return nil, err
}
if parentMemo != nil {
parent, err := s.convertMemoFromStore(ctx, parentMemo)
if err != nil {
return nil, err
}
memoMessage.Parent = parent
}
}
}
return memoMessage, nil
}

@ -80,7 +80,10 @@ func (s *APIV2Service) CreateMemo(ctx context.Context, request *apiv2pb.CreateMe
}
func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemosRequest) (*apiv2pb.ListMemosResponse, error) {
memoFind := &store.FindMemo{}
memoFind := &store.FindMemo{
// Exclude comments by default.
ExcludeComments: true,
}
if request.Filter != "" {
filter, err := parseListMemosFilter(request.Filter)
if err != nil {
@ -411,10 +414,13 @@ func (s *APIV2Service) GetUserMemosStats(ctx context.Context, request *apiv2pb.G
if user == nil {
return nil, status.Errorf(codes.NotFound, "user not found")
}
normalRowStatus := store.Normal
memos, err := s.Store.ListMemos(ctx, &store.FindMemo{
CreatorID: &user.ID,
RowStatus: &normalRowStatus,
CreatorID: &user.ID,
RowStatus: &normalRowStatus,
ExcludeComments: true,
ExcludeContent: true,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list memos")
@ -468,6 +474,7 @@ func (s *APIV2Service) convertMemoFromStore(ctx context.Context, memo *store.Mem
Nodes: convertFromASTNodes(rawNodes),
Visibility: convertVisibilityFromStore(memo.Visibility),
Pinned: memo.Pinned,
ParentId: memo.ParentID,
Relations: listMemoRelationsResponse.Relations,
Resources: listMemoResourcesResponse.Resources,
}, nil

@ -122,9 +122,11 @@ message Memo {
bool pinned = 11;
repeated Resource resources = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
optional int32 parent_id = 12;
repeated MemoRelation relations = 13 [(google.api.field_behavior) = OUTPUT_ONLY];
repeated Resource resources = 13 [(google.api.field_behavior) = OUTPUT_ONLY];
repeated MemoRelation relations = 14 [(google.api.field_behavior) = OUTPUT_ONLY];
}
message CreateMemoRequest {

@ -1935,6 +1935,7 @@
| nodes | [Node](#memos-api-v2-Node) | repeated | |
| visibility | [Visibility](#memos-api-v2-Visibility) | | |
| pinned | [bool](#bool) | | |
| parent_id | [int32](#int32) | optional | |
| resources | [Resource](#memos-api-v2-Resource) | repeated | |
| relations | [MemoRelation](#memos-api-v2-MemoRelation) | repeated | |

@ -93,8 +93,9 @@ type Memo struct {
Nodes []*Node `protobuf:"bytes,9,rep,name=nodes,proto3" json:"nodes,omitempty"`
Visibility Visibility `protobuf:"varint,10,opt,name=visibility,proto3,enum=memos.api.v2.Visibility" json:"visibility,omitempty"`
Pinned bool `protobuf:"varint,11,opt,name=pinned,proto3" json:"pinned,omitempty"`
Resources []*Resource `protobuf:"bytes,12,rep,name=resources,proto3" json:"resources,omitempty"`
Relations []*MemoRelation `protobuf:"bytes,13,rep,name=relations,proto3" json:"relations,omitempty"`
ParentId *int32 `protobuf:"varint,12,opt,name=parent_id,json=parentId,proto3,oneof" json:"parent_id,omitempty"`
Resources []*Resource `protobuf:"bytes,13,rep,name=resources,proto3" json:"resources,omitempty"`
Relations []*MemoRelation `protobuf:"bytes,14,rep,name=relations,proto3" json:"relations,omitempty"`
}
func (x *Memo) Reset() {
@ -206,6 +207,13 @@ func (x *Memo) GetPinned() bool {
return false
}
func (x *Memo) GetParentId() int32 {
if x != nil && x.ParentId != nil {
return *x.ParentId
}
return 0
}
func (x *Memo) GetResources() []*Resource {
if x != nil {
return x.Resources
@ -1416,7 +1424,7 @@ var file_api_v2_memo_service_proto_rawDesc = []byte{
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd0, 0x04, 0x0a, 0x04,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x05, 0x0a, 0x04,
0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
@ -1446,14 +1454,17 @@ var file_api_v2_memo_service_proto_rawDesc = []byte{
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06,
0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x69,
0x6e, 0x6e, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42,
0x03, 0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12,
0x3d, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03,
0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x67,
0x6e, 0x6e, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69,
0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x12, 0x3d, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x67,
0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a,
@ -2095,6 +2106,7 @@ func file_api_v2_memo_service_proto_init() {
}
}
}
file_api_v2_memo_service_proto_msgTypes[0].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

@ -55,9 +55,6 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
if v := find.CreatedTsAfter; v != nil {
where, args = append(where, "UNIX_TIMESTAMP(`memo`.`created_ts`) > ?"), append(args, *v)
}
if v := find.Pinned; v != nil {
where = append(where, "`memo_organizer`.`pinned` = 1")
}
if v := find.ContentSearch; len(v) != 0 {
for _, s := range v {
where, args = append(where, "`memo`.`content` LIKE ?"), append(args, "%"+s+"%")
@ -71,6 +68,10 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
}
where = append(where, fmt.Sprintf("`memo`.`visibility` in (%s)", strings.Join(placeholder, ",")))
}
if find.ExcludeComments {
where = append(where, "parent_id IS NULL")
}
orders := []string{}
if find.OrderByPinned {
orders = append(orders, "`pinned` DESC")
@ -91,6 +92,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
"`memo`.`content` AS `content`",
"`memo`.`visibility` AS `visibility`",
"MAX(CASE WHEN `memo_organizer`.`pinned` = 1 THEN 1 ELSE 0 END) AS `pinned`",
"(SELECT `related_memo_id` from `memo_relation` where `memo_id` = `id` AND `type` = \"COMMENT\" LIMIT 1) as `parent_id`",
}
query := "SELECT " + strings.Join(fields, ",\n") + " FROM `memo` LEFT JOIN `memo_organizer` ON `memo`.`id` = `memo_organizer`.`memo_id` WHERE " + strings.Join(where, " AND ") + " GROUP BY `memo`.`id` ORDER BY " + strings.Join(orders, ", ")
if find.Limit != nil {
@ -118,6 +120,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
&memo.Content,
&memo.Visibility,
&memo.Pinned,
&memo.ParentID,
); err != nil {
return nil, err
}

@ -59,8 +59,8 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
}
where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(holders, ", ")))
}
if v := find.Pinned; v != nil {
where = append(where, "memo_organizer.pinned = 1")
if find.ExcludeComments {
where = append(where, "parent_id IS NULL")
}
orders := []string{}
@ -82,6 +82,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
`memo.row_status AS row_status`,
`memo.visibility AS visibility`,
`MAX(CASE WHEN memo_organizer.pinned = 1 THEN 1 ELSE 0 END) AS pinned`,
"(SELECT related_memo_id from memo_relation where memo_id = id AND type = 'COMMENT' LIMIT 1) as parent_id",
}
if !find.ExcludeContent {
fields = append(fields, `memo.content AS content`)
@ -117,6 +118,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
&memo.RowStatus,
&memo.Visibility,
&memo.Pinned,
&memo.ParentID,
}
if !find.ExcludeContent {
dests = append(dests, &memo.Content)

@ -58,8 +58,8 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
}
where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(placeholder, ",")))
}
if v := find.Pinned; v != nil {
where = append(where, "memo_organizer.pinned = 1")
if find.ExcludeComments {
where = append(where, "parent_id IS NULL")
}
orders := []string{}
@ -81,6 +81,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
`memo.row_status AS row_status`,
`memo.visibility AS visibility`,
`CASE WHEN memo_organizer.pinned = 1 THEN 1 ELSE 0 END AS pinned`,
"(SELECT related_memo_id from memo_relation where memo_id = id AND type = \"COMMENT\" LIMIT 1) as parent_id",
}
if !find.ExcludeContent {
fields = append(fields, `memo.content AS content`)
@ -116,6 +117,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
&memo.RowStatus,
&memo.Visibility,
&memo.Pinned,
&memo.ParentID,
}
if !find.ExcludeContent {
dests = append(dests, &memo.Content)

@ -42,7 +42,8 @@ type Memo struct {
Visibility Visibility
// Composed fields
Pinned bool
Pinned bool
ParentID *int32
}
type FindMemo struct {
@ -55,10 +56,10 @@ type FindMemo struct {
CreatedTsBefore *int64
// Domain specific fields
ContentSearch []string
VisibilityList []Visibility
Pinned *bool
ExcludeContent bool
ContentSearch []string
VisibilityList []Visibility
ExcludeContent bool
ExcludeComments bool
// Pagination
Limit *int

@ -62,16 +62,13 @@ const MemoDetail = () => {
// Prepare memo comments.
useEffect(() => {
if (!memo) {
return;
}
(async () => {
const parentMemoId = memo.relations.find(
(relation) => relation.memoId === memo.id && relation.type === MemoRelation_Type.COMMENT
)?.relatedMemoId;
if (parentMemoId) {
memoStore.getOrFetchMemoById(parentMemoId).then((memo: Memo) => {
if (!memo) {
return;
}
if (memo.parentId) {
memoStore.getOrFetchMemoById(memo.parentId).then((memo: Memo) => {
setParentMemo(memo);
});
} else {

Loading…
Cancel
Save