Commit f6e5da44 authored by Steven's avatar Steven

refator: activity service

parent 4a20b529
...@@ -102,7 +102,7 @@ sh ./scripts/build.sh ...@@ -102,7 +102,7 @@ sh ./scripts/build.sh
cd web && pnpm build cd web && pnpm build
# Protocol buffer generation # Protocol buffer generation
buf generate cd proto && buf generate
# Linting # Linting
golangci-lint run --timeout=3m golangci-lint run --timeout=3m
......
...@@ -5,11 +5,17 @@ package memos.api.v1; ...@@ -5,11 +5,17 @@ package memos.api.v1;
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "google/api/client.proto"; import "google/api/client.proto";
import "google/api/field_behavior.proto"; import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
option go_package = "gen/api/v1"; option go_package = "gen/api/v1";
service ActivityService { 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. // GetActivity returns the activity with the given id.
rpc GetActivity(GetActivityRequest) returns (Activity) { rpc GetActivity(GetActivityRequest) returns (Activity) {
option (google.api.http) = {get: "/api/v1/{name=activities/*}"}; option (google.api.http) = {get: "/api/v1/{name=activities/*}"};
...@@ -18,40 +24,106 @@ service ActivityService { ...@@ -18,40 +24,106 @@ service ActivityService {
} }
message Activity { 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. // The name of the activity.
// Format: activities/{id} // Format: activities/{id}
string name = 1 [ string name = 1 [
(google.api.field_behavior) = OUTPUT_ONLY, (google.api.field_behavior) = OUTPUT_ONLY,
(google.api.field_behavior) = IDENTIFIER (google.api.field_behavior) = IDENTIFIER
]; ];
// The name of the creator. // The name of the creator.
// Format: users/{user} // Format: users/{user}
string creator = 2; string creator = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
// The type of the activity. // The type of the activity.
string type = 3; Type type = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
// The level of the activity. // The level of the activity.
string level = 4; Level level = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
// The create time of the activity. // The create time of the activity.
google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
// The payload of the activity. // 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 { 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. // ActivityMemoCommentPayload represents the payload of a memo comment activity.
message ActivityMemoCommentPayload { message ActivityMemoCommentPayload {
// The memo name of comment. // The memo name of comment.
// Refer to `Memo.name`. // Format: memos/{memo}
string memo = 1; string memo = 1;
// The name of related memo. // The name of related memo.
// Format: memos/{memo}
string related_memo = 2; 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 { message GetActivityRequest {
// The name of the activity. // The name of the activity.
// Format: activities/{id}, id is the system generated auto-incremented id. // 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"
}
];
} }
This diff is collapsed.
...@@ -35,6 +35,39 @@ var ( ...@@ -35,6 +35,39 @@ var (
_ = metadata.Join _ = 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) { 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 ( var (
protoReq GetActivityRequest protoReq GetActivityRequest
...@@ -78,6 +111,26 @@ func local_request_ActivityService_GetActivity_0(ctx context.Context, marshaler ...@@ -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. // 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. // 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 { 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) { 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()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
...@@ -138,6 +191,23 @@ func RegisterActivityServiceHandler(ctx context.Context, mux *runtime.ServeMux, ...@@ -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 // 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. // "ActivityServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ActivityServiceClient) error { 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) { 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()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
...@@ -159,9 +229,11 @@ func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.Serv ...@@ -159,9 +229,11 @@ func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.Serv
} }
var ( 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 ( var (
forward_ActivityService_GetActivity_0 = runtime.ForwardResponseMessage forward_ActivityService_ListActivities_0 = runtime.ForwardResponseMessage
forward_ActivityService_GetActivity_0 = runtime.ForwardResponseMessage
) )
...@@ -19,13 +19,16 @@ import ( ...@@ -19,13 +19,16 @@ import (
const _ = grpc.SupportPackageIsVersion9 const _ = grpc.SupportPackageIsVersion9
const ( 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. // 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. // 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 { 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 returns the activity with the given id.
GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*Activity, error) GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*Activity, error)
} }
...@@ -38,6 +41,16 @@ func NewActivityServiceClient(cc grpc.ClientConnInterface) ActivityServiceClient ...@@ -38,6 +41,16 @@ func NewActivityServiceClient(cc grpc.ClientConnInterface) ActivityServiceClient
return &activityServiceClient{cc} 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) { func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*Activity, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Activity) out := new(Activity)
...@@ -52,6 +65,8 @@ func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivity ...@@ -52,6 +65,8 @@ func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivity
// All implementations must embed UnimplementedActivityServiceServer // All implementations must embed UnimplementedActivityServiceServer
// for forward compatibility. // for forward compatibility.
type ActivityServiceServer interface { type ActivityServiceServer interface {
// ListActivities returns a list of activities.
ListActivities(context.Context, *ListActivitiesRequest) (*ListActivitiesResponse, error)
// GetActivity returns the activity with the given id. // GetActivity returns the activity with the given id.
GetActivity(context.Context, *GetActivityRequest) (*Activity, error) GetActivity(context.Context, *GetActivityRequest) (*Activity, error)
mustEmbedUnimplementedActivityServiceServer() mustEmbedUnimplementedActivityServiceServer()
...@@ -64,6 +79,9 @@ type ActivityServiceServer interface { ...@@ -64,6 +79,9 @@ type ActivityServiceServer interface {
// pointer dereference when methods are called. // pointer dereference when methods are called.
type UnimplementedActivityServiceServer struct{} 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) { func (UnimplementedActivityServiceServer) GetActivity(context.Context, *GetActivityRequest) (*Activity, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented")
} }
...@@ -88,6 +106,24 @@ func RegisterActivityServiceServer(s grpc.ServiceRegistrar, srv ActivityServiceS ...@@ -88,6 +106,24 @@ func RegisterActivityServiceServer(s grpc.ServiceRegistrar, srv ActivityServiceS
s.RegisterService(&ActivityService_ServiceDesc, srv) 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) { func _ActivityService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetActivityRequest) in := new(GetActivityRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
...@@ -113,6 +149,10 @@ var ActivityService_ServiceDesc = grpc.ServiceDesc{ ...@@ -113,6 +149,10 @@ var ActivityService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "memos.api.v1.ActivityService", ServiceName: "memos.api.v1.ActivityService",
HandlerType: (*ActivityServiceServer)(nil), HandlerType: (*ActivityServiceServer)(nil),
Methods: []grpc.MethodDesc{ Methods: []grpc.MethodDesc{
{
MethodName: "ListActivities",
Handler: _ActivityService_ListActivities_Handler,
},
{ {
MethodName: "GetActivity", MethodName: "GetActivity",
Handler: _ActivityService_GetActivity_Handler, Handler: _ActivityService_GetActivity_Handler,
......
...@@ -19,6 +19,39 @@ consumes: ...@@ -19,6 +19,39 @@ consumes:
produces: produces:
- application/json - application/json
paths: 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: /api/v1/auth/signin:
post: post:
summary: SignIn signs in the user. summary: SignIn signs in the user.
...@@ -2246,6 +2279,21 @@ paths: ...@@ -2246,6 +2279,21 @@ paths:
tags: tags:
- ResourceService - ResourceService
definitions: 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: ListNodeKind:
type: string type: string
enum: enum:
...@@ -2404,18 +2452,21 @@ definitions: ...@@ -2404,18 +2452,21 @@ definitions:
properties: properties:
memo: memo:
type: string type: string
description: |- title: |-
The memo name of comment. The memo name of comment.
Refer to `Memo.name`. Format: memos/{memo}
relatedMemo: relatedMemo:
type: string 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. description: ActivityMemoCommentPayload represents the payload of a memo comment activity.
apiv1ActivityPayload: apiv1ActivityPayload:
type: object type: object
properties: properties:
memoComment: memoComment:
$ref: '#/definitions/apiv1ActivityMemoCommentPayload' $ref: '#/definitions/apiv1ActivityMemoCommentPayload'
description: Memo comment activity payload.
apiv1FieldMapping: apiv1FieldMapping:
type: object type: object
properties: properties:
...@@ -2879,12 +2930,15 @@ definitions: ...@@ -2879,12 +2930,15 @@ definitions:
title: |- title: |-
The name of the creator. The name of the creator.
Format: users/{user} Format: users/{user}
readOnly: true
type: type:
type: string $ref: '#/definitions/v1ActivityType'
description: The type of the activity. description: The type of the activity.
readOnly: true
level: level:
type: string $ref: '#/definitions/ActivityLevel'
description: The level of the activity. description: The level of the activity.
readOnly: true
createTime: createTime:
type: string type: string
format: date-time format: date-time
...@@ -2893,6 +2947,20 @@ definitions: ...@@ -2893,6 +2947,20 @@ definitions:
payload: payload:
$ref: '#/definitions/apiv1ActivityPayload' $ref: '#/definitions/apiv1ActivityPayload'
description: The payload of the activity. 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: v1AutoLinkNode:
type: object type: object
properties: properties:
...@@ -3062,6 +3130,21 @@ definitions: ...@@ -3062,6 +3130,21 @@ definitions:
$ref: '#/definitions/v1Node' $ref: '#/definitions/v1Node'
url: url:
type: string 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: v1ListAllUserStatsResponse:
type: object type: object
properties: properties:
......
...@@ -14,6 +14,37 @@ import ( ...@@ -14,6 +14,37 @@ import (
"github.com/usememos/memos/store" "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) { func (s *APIV1Service) GetActivity(ctx context.Context, request *v1pb.GetActivityRequest) (*v1pb.Activity, error) {
activityID, err := ExtractActivityIDFromName(request.Name) activityID, err := ExtractActivityIDFromName(request.Name)
if err != nil { if err != nil {
...@@ -38,11 +69,30 @@ func (s *APIV1Service) convertActivityFromStore(ctx context.Context, activity *s ...@@ -38,11 +69,30 @@ func (s *APIV1Service) convertActivityFromStore(ctx context.Context, activity *s
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to convert activity payload from store: %v", err) 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{ return &v1pb.Activity{
Name: fmt.Sprintf("%s%d", ActivityNamePrefix, activity.ID), Name: fmt.Sprintf("%s%d", ActivityNamePrefix, activity.ID),
Creator: fmt.Sprintf("%s%d", UserNamePrefix, activity.CreatorID), Creator: fmt.Sprintf("%s%d", UserNamePrefix, activity.CreatorID),
Type: activity.Type.String(), Type: activityType,
Level: activity.Level.String(), Level: activityLevel,
CreateTime: timestamppb.New(time.Unix(activity.CreatedTs, 0)), CreateTime: timestamppb.New(time.Unix(activity.CreatedTs, 0)),
Payload: payload, Payload: payload,
}, nil }, nil
...@@ -65,9 +115,11 @@ func (s *APIV1Service) convertActivityPayloadFromStore(ctx context.Context, payl ...@@ -65,9 +115,11 @@ func (s *APIV1Service) convertActivityPayloadFromStore(ctx context.Context, payl
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get related memo: %v", err) return nil, status.Errorf(codes.Internal, "failed to get related memo: %v", err)
} }
v2Payload.MemoComment = &v1pb.ActivityMemoCommentPayload{ v2Payload.Payload = &v1pb.ActivityPayload_MemoComment{
Memo: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID), MemoComment: &v1pb.ActivityMemoCommentPayload{
RelatedMemo: fmt.Sprintf("%s%s", MemoNamePrefix, relatedMemo.UID), Memo: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID),
RelatedMemo: fmt.Sprintf("%s%s", MemoNamePrefix, relatedMemo.UID),
},
} }
} }
return v2Payload, nil return v2Payload, nil
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment