diff --git a/CLAUDE.md b/CLAUDE.md index 231f8401e..cb24c1995 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -102,7 +102,7 @@ sh ./scripts/build.sh cd web && pnpm build # Protocol buffer generation -buf generate +cd proto && buf generate # Linting golangci-lint run --timeout=3m diff --git a/proto/api/v1/activity_service.proto b/proto/api/v1/activity_service.proto index 015af06a0..bb675fff6 100644 --- a/proto/api/v1/activity_service.proto +++ b/proto/api/v1/activity_service.proto @@ -5,11 +5,17 @@ package memos.api.v1; import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v1"; service ActivityService { + // ListActivities returns a list of activities. + rpc ListActivities(ListActivitiesRequest) returns (ListActivitiesResponse) { + option (google.api.http) = {get: "/api/v1/activities"}; + } + // GetActivity returns the activity with the given id. rpc GetActivity(GetActivityRequest) returns (Activity) { option (google.api.http) = {get: "/api/v1/{name=activities/*}"}; @@ -18,40 +24,106 @@ service ActivityService { } message Activity { + option (google.api.resource) = { + type: "memos.api.v1/Activity" + pattern: "activities/{activity}" + name_field: "name" + singular: "activity" + plural: "activities" + }; + // The name of the activity. // Format: activities/{id} string name = 1 [ (google.api.field_behavior) = OUTPUT_ONLY, (google.api.field_behavior) = IDENTIFIER ]; + // The name of the creator. // Format: users/{user} - string creator = 2; + string creator = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; + // The type of the activity. - string type = 3; + Type type = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; + // The level of the activity. - string level = 4; + Level level = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; + // The create time of the activity. google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; + // The payload of the activity. - ActivityPayload payload = 6; + ActivityPayload payload = 6 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Activity types. + enum Type { + // Unspecified type. + TYPE_UNSPECIFIED = 0; + // Memo comment activity. + TYPE_MEMO_COMMENT = 1; + // Version update activity. + TYPE_VERSION_UPDATE = 2; + } + + // Activity levels. + enum Level { + // Unspecified level. + LEVEL_UNSPECIFIED = 0; + // Info level. + LEVEL_INFO = 1; + // Warn level. + LEVEL_WARN = 2; + // Error level. + LEVEL_ERROR = 3; + } } message ActivityPayload { - ActivityMemoCommentPayload memo_comment = 1; + oneof payload { + // Memo comment activity payload. + ActivityMemoCommentPayload memo_comment = 1; + } } // ActivityMemoCommentPayload represents the payload of a memo comment activity. message ActivityMemoCommentPayload { // The memo name of comment. - // Refer to `Memo.name`. + // Format: memos/{memo} string memo = 1; // The name of related memo. + // Format: memos/{memo} string related_memo = 2; } +message ListActivitiesRequest { + // The maximum number of activities to return. + // The service may return fewer than this value. + // If unspecified, at most 100 activities will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + int32 page_size = 1; + + // A page token, received from a previous `ListActivities` call. + // Provide this to retrieve the subsequent page. + string page_token = 2; +} + +message ListActivitiesResponse { + // The activities. + repeated Activity activities = 1; + + // A token to retrieve the next page of results. + // Pass this value in the page_token field in the subsequent call to `ListActivities` + // method to retrieve the next page of results. + string next_page_token = 2; +} + message GetActivityRequest { // The name of the activity. // Format: activities/{id}, id is the system generated auto-incremented id. - string name = 1; + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "memos.api.v1/Activity" + } + ]; } diff --git a/proto/gen/api/v1/activity_service.pb.go b/proto/gen/api/v1/activity_service.pb.go index 7744974a7..df7bbee52 100644 --- a/proto/gen/api/v1/activity_service.pb.go +++ b/proto/gen/api/v1/activity_service.pb.go @@ -23,6 +23,116 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Activity types. +type Activity_Type int32 + +const ( + // Unspecified type. + Activity_TYPE_UNSPECIFIED Activity_Type = 0 + // Memo comment activity. + Activity_TYPE_MEMO_COMMENT Activity_Type = 1 + // Version update activity. + Activity_TYPE_VERSION_UPDATE Activity_Type = 2 +) + +// Enum value maps for Activity_Type. +var ( + Activity_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "TYPE_MEMO_COMMENT", + 2: "TYPE_VERSION_UPDATE", + } + Activity_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "TYPE_MEMO_COMMENT": 1, + "TYPE_VERSION_UPDATE": 2, + } +) + +func (x Activity_Type) Enum() *Activity_Type { + p := new(Activity_Type) + *p = x + return p +} + +func (x Activity_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Activity_Type) Descriptor() protoreflect.EnumDescriptor { + return file_api_v1_activity_service_proto_enumTypes[0].Descriptor() +} + +func (Activity_Type) Type() protoreflect.EnumType { + return &file_api_v1_activity_service_proto_enumTypes[0] +} + +func (x Activity_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Activity_Type.Descriptor instead. +func (Activity_Type) EnumDescriptor() ([]byte, []int) { + return file_api_v1_activity_service_proto_rawDescGZIP(), []int{0, 0} +} + +// Activity levels. +type Activity_Level int32 + +const ( + // Unspecified level. + Activity_LEVEL_UNSPECIFIED Activity_Level = 0 + // Info level. + Activity_LEVEL_INFO Activity_Level = 1 + // Warn level. + Activity_LEVEL_WARN Activity_Level = 2 + // Error level. + Activity_LEVEL_ERROR Activity_Level = 3 +) + +// Enum value maps for Activity_Level. +var ( + Activity_Level_name = map[int32]string{ + 0: "LEVEL_UNSPECIFIED", + 1: "LEVEL_INFO", + 2: "LEVEL_WARN", + 3: "LEVEL_ERROR", + } + Activity_Level_value = map[string]int32{ + "LEVEL_UNSPECIFIED": 0, + "LEVEL_INFO": 1, + "LEVEL_WARN": 2, + "LEVEL_ERROR": 3, + } +) + +func (x Activity_Level) Enum() *Activity_Level { + p := new(Activity_Level) + *p = x + return p +} + +func (x Activity_Level) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Activity_Level) Descriptor() protoreflect.EnumDescriptor { + return file_api_v1_activity_service_proto_enumTypes[1].Descriptor() +} + +func (Activity_Level) Type() protoreflect.EnumType { + return &file_api_v1_activity_service_proto_enumTypes[1] +} + +func (x Activity_Level) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Activity_Level.Descriptor instead. +func (Activity_Level) EnumDescriptor() ([]byte, []int) { + return file_api_v1_activity_service_proto_rawDescGZIP(), []int{0, 1} +} + type Activity struct { state protoimpl.MessageState `protogen:"open.v1"` // The name of the activity. @@ -32,9 +142,9 @@ type Activity struct { // Format: users/{user} Creator string `protobuf:"bytes,2,opt,name=creator,proto3" json:"creator,omitempty"` // The type of the activity. - Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Type Activity_Type `protobuf:"varint,3,opt,name=type,proto3,enum=memos.api.v1.Activity_Type" json:"type,omitempty"` // The level of the activity. - Level string `protobuf:"bytes,4,opt,name=level,proto3" json:"level,omitempty"` + Level Activity_Level `protobuf:"varint,4,opt,name=level,proto3,enum=memos.api.v1.Activity_Level" json:"level,omitempty"` // The create time of the activity. CreateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // The payload of the activity. @@ -87,18 +197,18 @@ func (x *Activity) GetCreator() string { return "" } -func (x *Activity) GetType() string { +func (x *Activity) GetType() Activity_Type { if x != nil { return x.Type } - return "" + return Activity_TYPE_UNSPECIFIED } -func (x *Activity) GetLevel() string { +func (x *Activity) GetLevel() Activity_Level { if x != nil { return x.Level } - return "" + return Activity_LEVEL_UNSPECIFIED } func (x *Activity) GetCreateTime() *timestamppb.Timestamp { @@ -116,8 +226,11 @@ func (x *Activity) GetPayload() *ActivityPayload { } type ActivityPayload struct { - state protoimpl.MessageState `protogen:"open.v1"` - MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3" json:"memo_comment,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Payload: + // + // *ActivityPayload_MemoComment + Payload isActivityPayload_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -152,20 +265,41 @@ func (*ActivityPayload) Descriptor() ([]byte, []int) { return file_api_v1_activity_service_proto_rawDescGZIP(), []int{1} } -func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { +func (x *ActivityPayload) GetPayload() isActivityPayload_Payload { if x != nil { - return x.MemoComment + return x.Payload } return nil } +func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { + if x != nil { + if x, ok := x.Payload.(*ActivityPayload_MemoComment); ok { + return x.MemoComment + } + } + return nil +} + +type isActivityPayload_Payload interface { + isActivityPayload_Payload() +} + +type ActivityPayload_MemoComment struct { + // Memo comment activity payload. + MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3,oneof"` +} + +func (*ActivityPayload_MemoComment) isActivityPayload_Payload() {} + // ActivityMemoCommentPayload represents the payload of a memo comment activity. type ActivityMemoCommentPayload struct { state protoimpl.MessageState `protogen:"open.v1"` // The memo name of comment. - // Refer to `Memo.name`. + // Format: memos/{memo} Memo string `protobuf:"bytes,1,opt,name=memo,proto3" json:"memo,omitempty"` // The name of related memo. + // Format: memos/{memo} RelatedMemo string `protobuf:"bytes,2,opt,name=related_memo,json=relatedMemo,proto3" json:"related_memo,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -215,6 +349,120 @@ func (x *ActivityMemoCommentPayload) GetRelatedMemo() string { return "" } +type ListActivitiesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The maximum number of activities to return. + // The service may return fewer than this value. + // If unspecified, at most 100 activities will be returned. + // The maximum value is 1000; values above 1000 will be coerced to 1000. + PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListActivities` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListActivitiesRequest) Reset() { + *x = ListActivitiesRequest{} + mi := &file_api_v1_activity_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListActivitiesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActivitiesRequest) ProtoMessage() {} + +func (x *ListActivitiesRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_activity_service_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActivitiesRequest.ProtoReflect.Descriptor instead. +func (*ListActivitiesRequest) Descriptor() ([]byte, []int) { + return file_api_v1_activity_service_proto_rawDescGZIP(), []int{3} +} + +func (x *ListActivitiesRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListActivitiesRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +type ListActivitiesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The activities. + Activities []*Activity `protobuf:"bytes,1,rep,name=activities,proto3" json:"activities,omitempty"` + // A token to retrieve the next page of results. + // Pass this value in the page_token field in the subsequent call to `ListActivities` + // method to retrieve the next page of results. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListActivitiesResponse) Reset() { + *x = ListActivitiesResponse{} + mi := &file_api_v1_activity_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListActivitiesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActivitiesResponse) ProtoMessage() {} + +func (x *ListActivitiesResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_activity_service_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActivitiesResponse.ProtoReflect.Descriptor instead. +func (*ListActivitiesResponse) Descriptor() ([]byte, []int) { + return file_api_v1_activity_service_proto_rawDescGZIP(), []int{4} +} + +func (x *ListActivitiesResponse) GetActivities() []*Activity { + if x != nil { + return x.Activities + } + return nil +} + +func (x *ListActivitiesResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + type GetActivityRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // The name of the activity. @@ -226,7 +474,7 @@ type GetActivityRequest struct { func (x *GetActivityRequest) Reset() { *x = GetActivityRequest{} - mi := &file_api_v1_activity_service_proto_msgTypes[3] + mi := &file_api_v1_activity_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -238,7 +486,7 @@ func (x *GetActivityRequest) String() string { func (*GetActivityRequest) ProtoMessage() {} func (x *GetActivityRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_activity_service_proto_msgTypes[3] + mi := &file_api_v1_activity_service_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -251,7 +499,7 @@ func (x *GetActivityRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActivityRequest.ProtoReflect.Descriptor instead. func (*GetActivityRequest) Descriptor() ([]byte, []int) { - return file_api_v1_activity_service_proto_rawDescGZIP(), []int{3} + return file_api_v1_activity_service_proto_rawDescGZIP(), []int{5} } func (x *GetActivityRequest) GetName() string { @@ -265,23 +513,48 @@ var File_api_v1_activity_service_proto protoreflect.FileDescriptor const file_api_v1_activity_service_proto_rawDesc = "" + "\n" + - "\x1dapi/v1/activity_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xe5\x01\n" + + "\x1dapi/v1/activity_service.proto\x12\fmemos.api.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa2\x04\n" + "\bActivity\x12\x1a\n" + - "\x04name\x18\x01 \x01(\tB\x06\xe0A\x03\xe0A\bR\x04name\x12\x18\n" + - "\acreator\x18\x02 \x01(\tR\acreator\x12\x12\n" + - "\x04type\x18\x03 \x01(\tR\x04type\x12\x14\n" + - "\x05level\x18\x04 \x01(\tR\x05level\x12@\n" + + "\x04name\x18\x01 \x01(\tB\x06\xe0A\x03\xe0A\bR\x04name\x12\x1d\n" + + "\acreator\x18\x02 \x01(\tB\x03\xe0A\x03R\acreator\x124\n" + + "\x04type\x18\x03 \x01(\x0e2\x1b.memos.api.v1.Activity.TypeB\x03\xe0A\x03R\x04type\x127\n" + + "\x05level\x18\x04 \x01(\x0e2\x1c.memos.api.v1.Activity.LevelB\x03\xe0A\x03R\x05level\x12@\n" + "\vcreate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" + - "createTime\x127\n" + - "\apayload\x18\x06 \x01(\v2\x1d.memos.api.v1.ActivityPayloadR\apayload\"^\n" + - "\x0fActivityPayload\x12K\n" + - "\fmemo_comment\x18\x01 \x01(\v2(.memos.api.v1.ActivityMemoCommentPayloadR\vmemoComment\"S\n" + + "createTime\x12<\n" + + "\apayload\x18\x06 \x01(\v2\x1d.memos.api.v1.ActivityPayloadB\x03\xe0A\x03R\apayload\"L\n" + + "\x04Type\x12\x14\n" + + "\x10TYPE_UNSPECIFIED\x10\x00\x12\x15\n" + + "\x11TYPE_MEMO_COMMENT\x10\x01\x12\x17\n" + + "\x13TYPE_VERSION_UPDATE\x10\x02\"O\n" + + "\x05Level\x12\x15\n" + + "\x11LEVEL_UNSPECIFIED\x10\x00\x12\x0e\n" + + "\n" + + "LEVEL_INFO\x10\x01\x12\x0e\n" + + "\n" + + "LEVEL_WARN\x10\x02\x12\x0f\n" + + "\vLEVEL_ERROR\x10\x03:M\xeaAJ\n" + + "\x15memos.api.v1/Activity\x12\x15activities/{activity}\x1a\x04name*\n" + + "activities2\bactivity\"k\n" + + "\x0fActivityPayload\x12M\n" + + "\fmemo_comment\x18\x01 \x01(\v2(.memos.api.v1.ActivityMemoCommentPayloadH\x00R\vmemoCommentB\t\n" + + "\apayload\"S\n" + "\x1aActivityMemoCommentPayload\x12\x12\n" + "\x04memo\x18\x01 \x01(\tR\x04memo\x12!\n" + - "\frelated_memo\x18\x02 \x01(\tR\vrelatedMemo\"(\n" + - "\x12GetActivityRequest\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name2\x86\x01\n" + - "\x0fActivityService\x12s\n" + + "\frelated_memo\x18\x02 \x01(\tR\vrelatedMemo\"S\n" + + "\x15ListActivitiesRequest\x12\x1b\n" + + "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + + "\n" + + "page_token\x18\x02 \x01(\tR\tpageToken\"x\n" + + "\x16ListActivitiesResponse\x126\n" + + "\n" + + "activities\x18\x01 \x03(\v2\x16.memos.api.v1.ActivityR\n" + + "activities\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"G\n" + + "\x12GetActivityRequest\x121\n" + + "\x04name\x18\x01 \x01(\tB\x1d\xe0A\x02\xfaA\x17\n" + + "\x15memos.api.v1/ActivityR\x04name2\xff\x01\n" + + "\x0fActivityService\x12w\n" + + "\x0eListActivities\x12#.memos.api.v1.ListActivitiesRequest\x1a$.memos.api.v1.ListActivitiesResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\x12\x12/api/v1/activities\x12s\n" + "\vGetActivity\x12 .memos.api.v1.GetActivityRequest\x1a\x16.memos.api.v1.Activity\"*\xdaA\x04name\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/v1/{name=activities/*}B\xac\x01\n" + "\x10com.memos.api.v1B\x14ActivityServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3" @@ -297,25 +570,35 @@ func file_api_v1_activity_service_proto_rawDescGZIP() []byte { return file_api_v1_activity_service_proto_rawDescData } -var file_api_v1_activity_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_api_v1_activity_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_api_v1_activity_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_api_v1_activity_service_proto_goTypes = []any{ - (*Activity)(nil), // 0: memos.api.v1.Activity - (*ActivityPayload)(nil), // 1: memos.api.v1.ActivityPayload - (*ActivityMemoCommentPayload)(nil), // 2: memos.api.v1.ActivityMemoCommentPayload - (*GetActivityRequest)(nil), // 3: memos.api.v1.GetActivityRequest - (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp + (Activity_Type)(0), // 0: memos.api.v1.Activity.Type + (Activity_Level)(0), // 1: memos.api.v1.Activity.Level + (*Activity)(nil), // 2: memos.api.v1.Activity + (*ActivityPayload)(nil), // 3: memos.api.v1.ActivityPayload + (*ActivityMemoCommentPayload)(nil), // 4: memos.api.v1.ActivityMemoCommentPayload + (*ListActivitiesRequest)(nil), // 5: memos.api.v1.ListActivitiesRequest + (*ListActivitiesResponse)(nil), // 6: memos.api.v1.ListActivitiesResponse + (*GetActivityRequest)(nil), // 7: memos.api.v1.GetActivityRequest + (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp } var file_api_v1_activity_service_proto_depIdxs = []int32{ - 4, // 0: memos.api.v1.Activity.create_time:type_name -> google.protobuf.Timestamp - 1, // 1: memos.api.v1.Activity.payload:type_name -> memos.api.v1.ActivityPayload - 2, // 2: memos.api.v1.ActivityPayload.memo_comment:type_name -> memos.api.v1.ActivityMemoCommentPayload - 3, // 3: memos.api.v1.ActivityService.GetActivity:input_type -> memos.api.v1.GetActivityRequest - 0, // 4: memos.api.v1.ActivityService.GetActivity:output_type -> memos.api.v1.Activity - 4, // [4:5] is the sub-list for method output_type - 3, // [3:4] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 0, // 0: memos.api.v1.Activity.type:type_name -> memos.api.v1.Activity.Type + 1, // 1: memos.api.v1.Activity.level:type_name -> memos.api.v1.Activity.Level + 8, // 2: memos.api.v1.Activity.create_time:type_name -> google.protobuf.Timestamp + 3, // 3: memos.api.v1.Activity.payload:type_name -> memos.api.v1.ActivityPayload + 4, // 4: memos.api.v1.ActivityPayload.memo_comment:type_name -> memos.api.v1.ActivityMemoCommentPayload + 2, // 5: memos.api.v1.ListActivitiesResponse.activities:type_name -> memos.api.v1.Activity + 5, // 6: memos.api.v1.ActivityService.ListActivities:input_type -> memos.api.v1.ListActivitiesRequest + 7, // 7: memos.api.v1.ActivityService.GetActivity:input_type -> memos.api.v1.GetActivityRequest + 6, // 8: memos.api.v1.ActivityService.ListActivities:output_type -> memos.api.v1.ListActivitiesResponse + 2, // 9: memos.api.v1.ActivityService.GetActivity:output_type -> memos.api.v1.Activity + 8, // [8:10] is the sub-list for method output_type + 6, // [6:8] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_api_v1_activity_service_proto_init() } @@ -323,18 +606,22 @@ func file_api_v1_activity_service_proto_init() { if File_api_v1_activity_service_proto != nil { return } + file_api_v1_activity_service_proto_msgTypes[1].OneofWrappers = []any{ + (*ActivityPayload_MemoComment)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_activity_service_proto_rawDesc), len(file_api_v1_activity_service_proto_rawDesc)), - NumEnums: 0, - NumMessages: 4, + NumEnums: 2, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, GoTypes: file_api_v1_activity_service_proto_goTypes, DependencyIndexes: file_api_v1_activity_service_proto_depIdxs, + EnumInfos: file_api_v1_activity_service_proto_enumTypes, MessageInfos: file_api_v1_activity_service_proto_msgTypes, }.Build() File_api_v1_activity_service_proto = out.File diff --git a/proto/gen/api/v1/activity_service.pb.gw.go b/proto/gen/api/v1/activity_service.pb.gw.go index 7cbdd2c6d..cd4e81436 100644 --- a/proto/gen/api/v1/activity_service.pb.gw.go +++ b/proto/gen/api/v1/activity_service.pb.gw.go @@ -35,6 +35,39 @@ var ( _ = metadata.Join ) +var filter_ActivityService_ListActivities_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + +func request_ActivityService_ListActivities_0(ctx context.Context, marshaler runtime.Marshaler, client ActivityServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq ListActivitiesRequest + metadata runtime.ServerMetadata + ) + io.Copy(io.Discard, req.Body) + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ActivityService_ListActivities_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.ListActivities(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_ActivityService_ListActivities_0(ctx context.Context, marshaler runtime.Marshaler, server ActivityServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq ListActivitiesRequest + metadata runtime.ServerMetadata + ) + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ActivityService_ListActivities_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.ListActivities(ctx, &protoReq) + return msg, metadata, err +} + func request_ActivityService_GetActivity_0(ctx context.Context, marshaler runtime.Marshaler, client ActivityServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var ( protoReq GetActivityRequest @@ -78,6 +111,26 @@ func local_request_ActivityService_GetActivity_0(ctx context.Context, marshaler // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterActivityServiceHandlerFromEndpoint instead. // GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterActivityServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ActivityServiceServer) error { + mux.Handle(http.MethodGet, pattern_ActivityService_ListActivities_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.ActivityService/ListActivities", runtime.WithHTTPPathPattern("/api/v1/activities")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ActivityService_ListActivities_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_ActivityService_ListActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) mux.Handle(http.MethodGet, pattern_ActivityService_GetActivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -138,6 +191,23 @@ func RegisterActivityServiceHandler(ctx context.Context, mux *runtime.ServeMux, // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in // "ActivityServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares. func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ActivityServiceClient) error { + mux.Handle(http.MethodGet, pattern_ActivityService_ListActivities_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.ActivityService/ListActivities", runtime.WithHTTPPathPattern("/api/v1/activities")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ActivityService_ListActivities_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_ActivityService_ListActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) mux.Handle(http.MethodGet, pattern_ActivityService_GetActivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -159,9 +229,11 @@ func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.Serv } var ( - pattern_ActivityService_GetActivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "activities", "name"}, "")) + pattern_ActivityService_ListActivities_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "activities"}, "")) + pattern_ActivityService_GetActivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "activities", "name"}, "")) ) var ( - forward_ActivityService_GetActivity_0 = runtime.ForwardResponseMessage + forward_ActivityService_ListActivities_0 = runtime.ForwardResponseMessage + forward_ActivityService_GetActivity_0 = runtime.ForwardResponseMessage ) diff --git a/proto/gen/api/v1/activity_service_grpc.pb.go b/proto/gen/api/v1/activity_service_grpc.pb.go index 787ac80b3..d9d0594ef 100644 --- a/proto/gen/api/v1/activity_service_grpc.pb.go +++ b/proto/gen/api/v1/activity_service_grpc.pb.go @@ -19,13 +19,16 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - ActivityService_GetActivity_FullMethodName = "/memos.api.v1.ActivityService/GetActivity" + ActivityService_ListActivities_FullMethodName = "/memos.api.v1.ActivityService/ListActivities" + ActivityService_GetActivity_FullMethodName = "/memos.api.v1.ActivityService/GetActivity" ) // ActivityServiceClient is the client API for ActivityService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ActivityServiceClient interface { + // ListActivities returns a list of activities. + ListActivities(ctx context.Context, in *ListActivitiesRequest, opts ...grpc.CallOption) (*ListActivitiesResponse, error) // GetActivity returns the activity with the given id. GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*Activity, error) } @@ -38,6 +41,16 @@ func NewActivityServiceClient(cc grpc.ClientConnInterface) ActivityServiceClient return &activityServiceClient{cc} } +func (c *activityServiceClient) ListActivities(ctx context.Context, in *ListActivitiesRequest, opts ...grpc.CallOption) (*ListActivitiesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListActivitiesResponse) + err := c.cc.Invoke(ctx, ActivityService_ListActivities_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*Activity, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Activity) @@ -52,6 +65,8 @@ func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivity // All implementations must embed UnimplementedActivityServiceServer // for forward compatibility. type ActivityServiceServer interface { + // ListActivities returns a list of activities. + ListActivities(context.Context, *ListActivitiesRequest) (*ListActivitiesResponse, error) // GetActivity returns the activity with the given id. GetActivity(context.Context, *GetActivityRequest) (*Activity, error) mustEmbedUnimplementedActivityServiceServer() @@ -64,6 +79,9 @@ type ActivityServiceServer interface { // pointer dereference when methods are called. type UnimplementedActivityServiceServer struct{} +func (UnimplementedActivityServiceServer) ListActivities(context.Context, *ListActivitiesRequest) (*ListActivitiesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListActivities not implemented") +} func (UnimplementedActivityServiceServer) GetActivity(context.Context, *GetActivityRequest) (*Activity, error) { return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") } @@ -88,6 +106,24 @@ func RegisterActivityServiceServer(s grpc.ServiceRegistrar, srv ActivityServiceS s.RegisterService(&ActivityService_ServiceDesc, srv) } +func _ActivityService_ListActivities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListActivitiesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ActivityServiceServer).ListActivities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ActivityService_ListActivities_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ActivityServiceServer).ListActivities(ctx, req.(*ListActivitiesRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ActivityService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetActivityRequest) if err := dec(in); err != nil { @@ -113,6 +149,10 @@ var ActivityService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "memos.api.v1.ActivityService", HandlerType: (*ActivityServiceServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "ListActivities", + Handler: _ActivityService_ListActivities_Handler, + }, { MethodName: "GetActivity", Handler: _ActivityService_GetActivity_Handler, diff --git a/proto/gen/apidocs.swagger.yaml b/proto/gen/apidocs.swagger.yaml index de043524d..1bede9dce 100644 --- a/proto/gen/apidocs.swagger.yaml +++ b/proto/gen/apidocs.swagger.yaml @@ -19,6 +19,39 @@ consumes: produces: - application/json paths: + /api/v1/activities: + get: + summary: ListActivities returns a list of activities. + operationId: ActivityService_ListActivities + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1ListActivitiesResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: pageSize + description: |- + The maximum number of activities to return. + The service may return fewer than this value. + If unspecified, at most 100 activities will be returned. + The maximum value is 1000; values above 1000 will be coerced to 1000. + in: query + required: false + type: integer + format: int32 + - name: pageToken + description: |- + A page token, received from a previous `ListActivities` call. + Provide this to retrieve the subsequent page. + in: query + required: false + type: string + tags: + - ActivityService /api/v1/auth/signin: post: summary: SignIn signs in the user. @@ -2246,6 +2279,21 @@ paths: tags: - ResourceService definitions: + ActivityLevel: + type: string + enum: + - LEVEL_UNSPECIFIED + - LEVEL_INFO + - LEVEL_WARN + - LEVEL_ERROR + default: LEVEL_UNSPECIFIED + description: |- + Activity levels. + + - LEVEL_UNSPECIFIED: Unspecified level. + - LEVEL_INFO: Info level. + - LEVEL_WARN: Warn level. + - LEVEL_ERROR: Error level. ListNodeKind: type: string enum: @@ -2404,18 +2452,21 @@ definitions: properties: memo: type: string - description: |- + title: |- The memo name of comment. - Refer to `Memo.name`. + Format: memos/{memo} relatedMemo: type: string - description: The name of related memo. + title: |- + The name of related memo. + Format: memos/{memo} description: ActivityMemoCommentPayload represents the payload of a memo comment activity. apiv1ActivityPayload: type: object properties: memoComment: $ref: '#/definitions/apiv1ActivityMemoCommentPayload' + description: Memo comment activity payload. apiv1FieldMapping: type: object properties: @@ -2879,12 +2930,15 @@ definitions: title: |- The name of the creator. Format: users/{user} + readOnly: true type: - type: string + $ref: '#/definitions/v1ActivityType' description: The type of the activity. + readOnly: true level: - type: string + $ref: '#/definitions/ActivityLevel' description: The level of the activity. + readOnly: true createTime: type: string format: date-time @@ -2893,6 +2947,20 @@ definitions: payload: $ref: '#/definitions/apiv1ActivityPayload' description: The payload of the activity. + readOnly: true + v1ActivityType: + type: string + enum: + - TYPE_UNSPECIFIED + - TYPE_MEMO_COMMENT + - TYPE_VERSION_UPDATE + default: TYPE_UNSPECIFIED + description: |- + Activity types. + + - TYPE_UNSPECIFIED: Unspecified type. + - TYPE_MEMO_COMMENT: Memo comment activity. + - TYPE_VERSION_UPDATE: Version update activity. v1AutoLinkNode: type: object properties: @@ -3062,6 +3130,21 @@ definitions: $ref: '#/definitions/v1Node' url: type: string + v1ListActivitiesResponse: + type: object + properties: + activities: + type: array + items: + type: object + $ref: '#/definitions/v1Activity' + description: The activities. + nextPageToken: + type: string + description: |- + A token to retrieve the next page of results. + Pass this value in the page_token field in the subsequent call to `ListActivities` + method to retrieve the next page of results. v1ListAllUserStatsResponse: type: object properties: diff --git a/server/router/api/v1/activity_service.go b/server/router/api/v1/activity_service.go index b315fef5e..4734d93bb 100644 --- a/server/router/api/v1/activity_service.go +++ b/server/router/api/v1/activity_service.go @@ -14,6 +14,37 @@ import ( "github.com/usememos/memos/store" ) +func (s *APIV1Service) ListActivities(ctx context.Context, request *v1pb.ListActivitiesRequest) (*v1pb.ListActivitiesResponse, error) { + // Set default page size if not specified + pageSize := request.PageSize + if pageSize <= 0 || pageSize > 1000 { + pageSize = 100 + } + + // TODO: Implement pagination with page_token and use pageSize for limiting + // For now, we'll fetch all activities and the pageSize will be used in future pagination implementation + _ = pageSize // Acknowledge pageSize variable to avoid linter warning + + activities, err := s.Store.ListActivities(ctx, &store.FindActivity{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list activities: %v", err) + } + + var activityMessages []*v1pb.Activity + for _, activity := range activities { + activityMessage, err := s.convertActivityFromStore(ctx, activity) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert activity from store: %v", err) + } + activityMessages = append(activityMessages, activityMessage) + } + + return &v1pb.ListActivitiesResponse{ + Activities: activityMessages, + // TODO: Implement next_page_token for pagination + }, nil +} + func (s *APIV1Service) GetActivity(ctx context.Context, request *v1pb.GetActivityRequest) (*v1pb.Activity, error) { activityID, err := ExtractActivityIDFromName(request.Name) if err != nil { @@ -38,11 +69,30 @@ func (s *APIV1Service) convertActivityFromStore(ctx context.Context, activity *s if err != nil { return nil, status.Errorf(codes.Internal, "failed to convert activity payload from store: %v", err) } + + // Convert store activity type to proto enum + var activityType v1pb.Activity_Type + switch activity.Type { + case store.ActivityTypeMemoComment: + activityType = v1pb.Activity_TYPE_MEMO_COMMENT + default: + activityType = v1pb.Activity_TYPE_UNSPECIFIED + } + + // Convert store activity level to proto enum + var activityLevel v1pb.Activity_Level + switch activity.Level { + case store.ActivityLevelInfo: + activityLevel = v1pb.Activity_LEVEL_INFO + default: + activityLevel = v1pb.Activity_LEVEL_UNSPECIFIED + } + return &v1pb.Activity{ Name: fmt.Sprintf("%s%d", ActivityNamePrefix, activity.ID), Creator: fmt.Sprintf("%s%d", UserNamePrefix, activity.CreatorID), - Type: activity.Type.String(), - Level: activity.Level.String(), + Type: activityType, + Level: activityLevel, CreateTime: timestamppb.New(time.Unix(activity.CreatedTs, 0)), Payload: payload, }, nil @@ -65,9 +115,11 @@ func (s *APIV1Service) convertActivityPayloadFromStore(ctx context.Context, payl if err != nil { return nil, status.Errorf(codes.Internal, "failed to get related memo: %v", err) } - v2Payload.MemoComment = &v1pb.ActivityMemoCommentPayload{ - Memo: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID), - RelatedMemo: fmt.Sprintf("%s%s", MemoNamePrefix, relatedMemo.UID), + v2Payload.Payload = &v1pb.ActivityPayload_MemoComment{ + MemoComment: &v1pb.ActivityMemoCommentPayload{ + Memo: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID), + RelatedMemo: fmt.Sprintf("%s%s", MemoNamePrefix, relatedMemo.UID), + }, } } return v2Payload, nil diff --git a/web/src/types/proto/api/v1/activity_service.ts b/web/src/types/proto/api/v1/activity_service.ts index 6543a4535..09719e10b 100644 --- a/web/src/types/proto/api/v1/activity_service.ts +++ b/web/src/types/proto/api/v1/activity_service.ts @@ -22,9 +22,9 @@ export interface Activity { */ creator: string; /** The type of the activity. */ - type: string; + type: Activity_Type; /** The level of the activity. */ - level: string; + level: Activity_Level; /** The create time of the activity. */ createTime?: | Date @@ -33,7 +33,101 @@ export interface Activity { payload?: ActivityPayload | undefined; } +/** Activity types. */ +export enum Activity_Type { + /** TYPE_UNSPECIFIED - Unspecified type. */ + TYPE_UNSPECIFIED = "TYPE_UNSPECIFIED", + /** TYPE_MEMO_COMMENT - Memo comment activity. */ + TYPE_MEMO_COMMENT = "TYPE_MEMO_COMMENT", + /** TYPE_VERSION_UPDATE - Version update activity. */ + TYPE_VERSION_UPDATE = "TYPE_VERSION_UPDATE", + UNRECOGNIZED = "UNRECOGNIZED", +} + +export function activity_TypeFromJSON(object: any): Activity_Type { + switch (object) { + case 0: + case "TYPE_UNSPECIFIED": + return Activity_Type.TYPE_UNSPECIFIED; + case 1: + case "TYPE_MEMO_COMMENT": + return Activity_Type.TYPE_MEMO_COMMENT; + case 2: + case "TYPE_VERSION_UPDATE": + return Activity_Type.TYPE_VERSION_UPDATE; + case -1: + case "UNRECOGNIZED": + default: + return Activity_Type.UNRECOGNIZED; + } +} + +export function activity_TypeToNumber(object: Activity_Type): number { + switch (object) { + case Activity_Type.TYPE_UNSPECIFIED: + return 0; + case Activity_Type.TYPE_MEMO_COMMENT: + return 1; + case Activity_Type.TYPE_VERSION_UPDATE: + return 2; + case Activity_Type.UNRECOGNIZED: + default: + return -1; + } +} + +/** Activity levels. */ +export enum Activity_Level { + /** LEVEL_UNSPECIFIED - Unspecified level. */ + LEVEL_UNSPECIFIED = "LEVEL_UNSPECIFIED", + /** LEVEL_INFO - Info level. */ + LEVEL_INFO = "LEVEL_INFO", + /** LEVEL_WARN - Warn level. */ + LEVEL_WARN = "LEVEL_WARN", + /** LEVEL_ERROR - Error level. */ + LEVEL_ERROR = "LEVEL_ERROR", + UNRECOGNIZED = "UNRECOGNIZED", +} + +export function activity_LevelFromJSON(object: any): Activity_Level { + switch (object) { + case 0: + case "LEVEL_UNSPECIFIED": + return Activity_Level.LEVEL_UNSPECIFIED; + case 1: + case "LEVEL_INFO": + return Activity_Level.LEVEL_INFO; + case 2: + case "LEVEL_WARN": + return Activity_Level.LEVEL_WARN; + case 3: + case "LEVEL_ERROR": + return Activity_Level.LEVEL_ERROR; + case -1: + case "UNRECOGNIZED": + default: + return Activity_Level.UNRECOGNIZED; + } +} + +export function activity_LevelToNumber(object: Activity_Level): number { + switch (object) { + case Activity_Level.LEVEL_UNSPECIFIED: + return 0; + case Activity_Level.LEVEL_INFO: + return 1; + case Activity_Level.LEVEL_WARN: + return 2; + case Activity_Level.LEVEL_ERROR: + return 3; + case Activity_Level.UNRECOGNIZED: + default: + return -1; + } +} + export interface ActivityPayload { + /** Memo comment activity payload. */ memoComment?: ActivityMemoCommentPayload | undefined; } @@ -41,13 +135,42 @@ export interface ActivityPayload { export interface ActivityMemoCommentPayload { /** * The memo name of comment. - * Refer to `Memo.name`. + * Format: memos/{memo} */ memo: string; - /** The name of related memo. */ + /** + * The name of related memo. + * Format: memos/{memo} + */ relatedMemo: string; } +export interface ListActivitiesRequest { + /** + * The maximum number of activities to return. + * The service may return fewer than this value. + * If unspecified, at most 100 activities will be returned. + * The maximum value is 1000; values above 1000 will be coerced to 1000. + */ + pageSize: number; + /** + * A page token, received from a previous `ListActivities` call. + * Provide this to retrieve the subsequent page. + */ + pageToken: string; +} + +export interface ListActivitiesResponse { + /** The activities. */ + activities: Activity[]; + /** + * A token to retrieve the next page of results. + * Pass this value in the page_token field in the subsequent call to `ListActivities` + * method to retrieve the next page of results. + */ + nextPageToken: string; +} + export interface GetActivityRequest { /** * The name of the activity. @@ -57,7 +180,14 @@ export interface GetActivityRequest { } function createBaseActivity(): Activity { - return { name: "", creator: "", type: "", level: "", createTime: undefined, payload: undefined }; + return { + name: "", + creator: "", + type: Activity_Type.TYPE_UNSPECIFIED, + level: Activity_Level.LEVEL_UNSPECIFIED, + createTime: undefined, + payload: undefined, + }; } export const Activity: MessageFns = { @@ -68,11 +198,11 @@ export const Activity: MessageFns = { if (message.creator !== "") { writer.uint32(18).string(message.creator); } - if (message.type !== "") { - writer.uint32(26).string(message.type); + if (message.type !== Activity_Type.TYPE_UNSPECIFIED) { + writer.uint32(24).int32(activity_TypeToNumber(message.type)); } - if (message.level !== "") { - writer.uint32(34).string(message.level); + if (message.level !== Activity_Level.LEVEL_UNSPECIFIED) { + writer.uint32(32).int32(activity_LevelToNumber(message.level)); } if (message.createTime !== undefined) { Timestamp.encode(toTimestamp(message.createTime), writer.uint32(42).fork()).join(); @@ -107,19 +237,19 @@ export const Activity: MessageFns = { continue; } case 3: { - if (tag !== 26) { + if (tag !== 24) { break; } - message.type = reader.string(); + message.type = activity_TypeFromJSON(reader.int32()); continue; } case 4: { - if (tag !== 34) { + if (tag !== 32) { break; } - message.level = reader.string(); + message.level = activity_LevelFromJSON(reader.int32()); continue; } case 5: { @@ -154,8 +284,8 @@ export const Activity: MessageFns = { const message = createBaseActivity(); message.name = object.name ?? ""; message.creator = object.creator ?? ""; - message.type = object.type ?? ""; - message.level = object.level ?? ""; + message.type = object.type ?? Activity_Type.TYPE_UNSPECIFIED; + message.level = object.level ?? Activity_Level.LEVEL_UNSPECIFIED; message.createTime = object.createTime ?? undefined; message.payload = (object.payload !== undefined && object.payload !== null) ? ActivityPayload.fromPartial(object.payload) @@ -270,6 +400,122 @@ export const ActivityMemoCommentPayload: MessageFns }, }; +function createBaseListActivitiesRequest(): ListActivitiesRequest { + return { pageSize: 0, pageToken: "" }; +} + +export const ListActivitiesRequest: MessageFns = { + encode(message: ListActivitiesRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.pageSize !== 0) { + writer.uint32(8).int32(message.pageSize); + } + if (message.pageToken !== "") { + writer.uint32(18).string(message.pageToken); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ListActivitiesRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseListActivitiesRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.pageSize = reader.int32(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.pageToken = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + create(base?: DeepPartial): ListActivitiesRequest { + return ListActivitiesRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ListActivitiesRequest { + const message = createBaseListActivitiesRequest(); + message.pageSize = object.pageSize ?? 0; + message.pageToken = object.pageToken ?? ""; + return message; + }, +}; + +function createBaseListActivitiesResponse(): ListActivitiesResponse { + return { activities: [], nextPageToken: "" }; +} + +export const ListActivitiesResponse: MessageFns = { + encode(message: ListActivitiesResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.activities) { + Activity.encode(v!, writer.uint32(10).fork()).join(); + } + if (message.nextPageToken !== "") { + writer.uint32(18).string(message.nextPageToken); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ListActivitiesResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseListActivitiesResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.activities.push(Activity.decode(reader, reader.uint32())); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.nextPageToken = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + create(base?: DeepPartial): ListActivitiesResponse { + return ListActivitiesResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ListActivitiesResponse { + const message = createBaseListActivitiesResponse(); + message.activities = object.activities?.map((e) => Activity.fromPartial(e)) || []; + message.nextPageToken = object.nextPageToken ?? ""; + return message; + }, +}; + function createBaseGetActivityRequest(): GetActivityRequest { return { name: "" }; } @@ -321,6 +567,43 @@ export const ActivityServiceDefinition = { name: "ActivityService", fullName: "memos.api.v1.ActivityService", methods: { + /** ListActivities returns a list of activities. */ + listActivities: { + name: "ListActivities", + requestType: ListActivitiesRequest, + requestStream: false, + responseType: ListActivitiesResponse, + responseStream: false, + options: { + _unknownFields: { + 578365826: [ + new Uint8Array([ + 20, + 18, + 18, + 47, + 97, + 112, + 105, + 47, + 118, + 49, + 47, + 97, + 99, + 116, + 105, + 118, + 105, + 116, + 105, + 101, + 115, + ]), + ], + }, + }, + }, /** GetActivity returns the activity with the given id. */ getActivity: { name: "GetActivity",