diff --git a/proto/api/v1/instance_service.proto b/proto/api/v1/instance_service.proto index f4ce3d501..b2e6c641a 100644 --- a/proto/api/v1/instance_service.proto +++ b/proto/api/v1/instance_service.proto @@ -8,6 +8,7 @@ import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/field_mask.proto"; +import "google/type/color.proto"; option go_package = "gen/api/v1"; @@ -69,6 +70,7 @@ message InstanceSetting { GeneralSetting general_setting = 2; StorageSetting storage_setting = 3; MemoRelatedSetting memo_related_setting = 4; + TagsSetting tags_setting = 5; } // Enumeration of instance setting keys. @@ -80,6 +82,8 @@ message InstanceSetting { STORAGE = 2; // MEMO_RELATED is the key for memo related settings. MEMO_RELATED = 3; + // TAGS is the key for tag metadata. + TAGS = 4; } // General instance settings configuration. @@ -159,6 +163,17 @@ message InstanceSetting { // reactions is the list of reactions. repeated string reactions = 7; } + + // Metadata for a tag. + message TagMetadata { + // Background color for the tag label. + google.type.Color background_color = 1; + } + + // Tag metadata configuration. + message TagsSetting { + map tags = 1; + } } // Request message for GetInstanceSetting method. diff --git a/proto/api/v1/user_service.proto b/proto/api/v1/user_service.proto index 6cd89e591..e30a5cccd 100644 --- a/proto/api/v1/user_service.proto +++ b/proto/api/v1/user_service.proto @@ -10,7 +10,6 @@ import "google/api/resource.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; -import "google/type/color.proto"; option go_package = "gen/api/v1"; @@ -376,7 +375,6 @@ message UserSetting { oneof value { GeneralSetting general_setting = 2; WebhooksSetting webhooks_setting = 5; - TagsSetting tags_setting = 6; } // Enumeration of user setting keys. @@ -386,8 +384,6 @@ message UserSetting { GENERAL = 1; // WEBHOOKS is the key for user webhooks. WEBHOOKS = 4; - // TAGS is the key for user tag metadata. - TAGS = 5; } // General user settings configuration. @@ -407,17 +403,6 @@ message UserSetting { // List of user webhooks. repeated UserWebhook webhooks = 1; } - - // Metadata for a tag. - message TagMetadata { - // Background color for the tag label. - google.type.Color background_color = 1; - } - - // User tag metadata configuration. - message TagsSetting { - map tags = 1; - } } message GetUserSettingRequest { diff --git a/proto/gen/api/v1/instance_service.pb.go b/proto/gen/api/v1/instance_service.pb.go index 5be2dd4bd..2dc3e0094 100644 --- a/proto/gen/api/v1/instance_service.pb.go +++ b/proto/gen/api/v1/instance_service.pb.go @@ -8,6 +8,7 @@ package apiv1 import ( _ "google.golang.org/genproto/googleapis/api/annotations" + color "google.golang.org/genproto/googleapis/type/color" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" @@ -34,6 +35,8 @@ const ( InstanceSetting_STORAGE InstanceSetting_Key = 2 // MEMO_RELATED is the key for memo related settings. InstanceSetting_MEMO_RELATED InstanceSetting_Key = 3 + // TAGS is the key for tag metadata. + InstanceSetting_TAGS InstanceSetting_Key = 4 ) // Enum value maps for InstanceSetting_Key. @@ -43,12 +46,14 @@ var ( 1: "GENERAL", 2: "STORAGE", 3: "MEMO_RELATED", + 4: "TAGS", } InstanceSetting_Key_value = map[string]int32{ "KEY_UNSPECIFIED": 0, "GENERAL": 1, "STORAGE": 2, "MEMO_RELATED": 3, + "TAGS": 4, } ) @@ -257,6 +262,7 @@ type InstanceSetting struct { // *InstanceSetting_GeneralSetting_ // *InstanceSetting_StorageSetting_ // *InstanceSetting_MemoRelatedSetting_ + // *InstanceSetting_TagsSetting_ Value isInstanceSetting_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -333,6 +339,15 @@ func (x *InstanceSetting) GetMemoRelatedSetting() *InstanceSetting_MemoRelatedSe return nil } +func (x *InstanceSetting) GetTagsSetting() *InstanceSetting_TagsSetting { + if x != nil { + if x, ok := x.Value.(*InstanceSetting_TagsSetting_); ok { + return x.TagsSetting + } + } + return nil +} + type isInstanceSetting_Value interface { isInstanceSetting_Value() } @@ -349,12 +364,18 @@ type InstanceSetting_MemoRelatedSetting_ struct { MemoRelatedSetting *InstanceSetting_MemoRelatedSetting `protobuf:"bytes,4,opt,name=memo_related_setting,json=memoRelatedSetting,proto3,oneof"` } +type InstanceSetting_TagsSetting_ struct { + TagsSetting *InstanceSetting_TagsSetting `protobuf:"bytes,5,opt,name=tags_setting,json=tagsSetting,proto3,oneof"` +} + func (*InstanceSetting_GeneralSetting_) isInstanceSetting_Value() {} func (*InstanceSetting_StorageSetting_) isInstanceSetting_Value() {} func (*InstanceSetting_MemoRelatedSetting_) isInstanceSetting_Value() {} +func (*InstanceSetting_TagsSetting_) isInstanceSetting_Value() {} + // Request message for GetInstanceSetting method. type GetInstanceSettingRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -724,6 +745,97 @@ func (x *InstanceSetting_MemoRelatedSetting) GetReactions() []string { return nil } +// Metadata for a tag. +type InstanceSetting_TagMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Background color for the tag label. + BackgroundColor *color.Color `protobuf:"bytes,1,opt,name=background_color,json=backgroundColor,proto3" json:"background_color,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InstanceSetting_TagMetadata) Reset() { + *x = InstanceSetting_TagMetadata{} + mi := &file_api_v1_instance_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InstanceSetting_TagMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstanceSetting_TagMetadata) ProtoMessage() {} + +func (x *InstanceSetting_TagMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_instance_service_proto_msgTypes[8] + 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 InstanceSetting_TagMetadata.ProtoReflect.Descriptor instead. +func (*InstanceSetting_TagMetadata) Descriptor() ([]byte, []int) { + return file_api_v1_instance_service_proto_rawDescGZIP(), []int{2, 3} +} + +func (x *InstanceSetting_TagMetadata) GetBackgroundColor() *color.Color { + if x != nil { + return x.BackgroundColor + } + return nil +} + +// Tag metadata configuration. +type InstanceSetting_TagsSetting struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tags map[string]*InstanceSetting_TagMetadata `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InstanceSetting_TagsSetting) Reset() { + *x = InstanceSetting_TagsSetting{} + mi := &file_api_v1_instance_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InstanceSetting_TagsSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstanceSetting_TagsSetting) ProtoMessage() {} + +func (x *InstanceSetting_TagsSetting) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_instance_service_proto_msgTypes[9] + 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 InstanceSetting_TagsSetting.ProtoReflect.Descriptor instead. +func (*InstanceSetting_TagsSetting) Descriptor() ([]byte, []int) { + return file_api_v1_instance_service_proto_rawDescGZIP(), []int{2, 4} +} + +func (x *InstanceSetting_TagsSetting) GetTags() map[string]*InstanceSetting_TagMetadata { + if x != nil { + return x.Tags + } + return nil +} + // Custom profile configuration for instance branding. type InstanceSetting_GeneralSetting_CustomProfile struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -736,7 +848,7 @@ type InstanceSetting_GeneralSetting_CustomProfile struct { func (x *InstanceSetting_GeneralSetting_CustomProfile) Reset() { *x = InstanceSetting_GeneralSetting_CustomProfile{} - mi := &file_api_v1_instance_service_proto_msgTypes[8] + mi := &file_api_v1_instance_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -748,7 +860,7 @@ func (x *InstanceSetting_GeneralSetting_CustomProfile) String() string { func (*InstanceSetting_GeneralSetting_CustomProfile) ProtoMessage() {} func (x *InstanceSetting_GeneralSetting_CustomProfile) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_instance_service_proto_msgTypes[8] + mi := &file_api_v1_instance_service_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -801,7 +913,7 @@ type InstanceSetting_StorageSetting_S3Config struct { func (x *InstanceSetting_StorageSetting_S3Config) Reset() { *x = InstanceSetting_StorageSetting_S3Config{} - mi := &file_api_v1_instance_service_proto_msgTypes[9] + mi := &file_api_v1_instance_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -813,7 +925,7 @@ func (x *InstanceSetting_StorageSetting_S3Config) String() string { func (*InstanceSetting_StorageSetting_S3Config) ProtoMessage() {} func (x *InstanceSetting_StorageSetting_S3Config) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_instance_service_proto_msgTypes[9] + mi := &file_api_v1_instance_service_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -875,18 +987,19 @@ var File_api_v1_instance_service_proto protoreflect.FileDescriptor const file_api_v1_instance_service_proto_rawDesc = "" + "\n" + - "\x1dapi/v1/instance_service.proto\x12\fmemos.api.v1\x1a\x19api/v1/user_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a google/protobuf/field_mask.proto\"\x8c\x01\n" + + "\x1dapi/v1/instance_service.proto\x12\fmemos.api.v1\x1a\x19api/v1/user_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x17google/type/color.proto\x1a google/protobuf/field_mask.proto\"\x8c\x01\n" + "\x0fInstanceProfile\x12\x18\n" + "\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" + "\x04demo\x18\x03 \x01(\bR\x04demo\x12!\n" + "\finstance_url\x18\x06 \x01(\tR\vinstanceUrl\x12(\n" + "\x05admin\x18\a \x01(\v2\x12.memos.api.v1.UserR\x05admin\"\x1b\n" + - "\x19GetInstanceProfileRequest\"\x99\x0f\n" + + "\x19GetInstanceProfileRequest\"\xfe\x11\n" + "\x0fInstanceSetting\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12W\n" + "\x0fgeneral_setting\x18\x02 \x01(\v2,.memos.api.v1.InstanceSetting.GeneralSettingH\x00R\x0egeneralSetting\x12W\n" + "\x0fstorage_setting\x18\x03 \x01(\v2,.memos.api.v1.InstanceSetting.StorageSettingH\x00R\x0estorageSetting\x12d\n" + - "\x14memo_related_setting\x18\x04 \x01(\v20.memos.api.v1.InstanceSetting.MemoRelatedSettingH\x00R\x12memoRelatedSetting\x1a\xca\x04\n" + + "\x14memo_related_setting\x18\x04 \x01(\v20.memos.api.v1.InstanceSetting.MemoRelatedSettingH\x00R\x12memoRelatedSetting\x12N\n" + + "\ftags_setting\x18\x05 \x01(\v2).memos.api.v1.InstanceSetting.TagsSettingH\x00R\vtagsSetting\x1a\xca\x04\n" + "\x0eGeneralSetting\x12<\n" + "\x1adisallow_user_registration\x18\x02 \x01(\bR\x18disallowUserRegistration\x124\n" + "\x16disallow_password_auth\x18\x03 \x01(\bR\x14disallowPasswordAuth\x12+\n" + @@ -922,12 +1035,20 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\x18display_with_update_time\x18\x02 \x01(\bR\x15displayWithUpdateTime\x120\n" + "\x14content_length_limit\x18\x03 \x01(\x05R\x12contentLengthLimit\x127\n" + "\x18enable_double_click_edit\x18\x04 \x01(\bR\x15enableDoubleClickEdit\x12\x1c\n" + - "\treactions\x18\a \x03(\tR\treactions\"F\n" + + "\treactions\x18\a \x03(\tR\treactions\x1aL\n" + + "\vTagMetadata\x12=\n" + + "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\x1a\xba\x01\n" + + "\vTagsSetting\x12G\n" + + "\x04tags\x18\x01 \x03(\v23.memos.api.v1.InstanceSetting.TagsSetting.TagsEntryR\x04tags\x1ab\n" + + "\tTagsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12?\n" + + "\x05value\x18\x02 \x01(\v2).memos.api.v1.InstanceSetting.TagMetadataR\x05value:\x028\x01\"P\n" + "\x03Key\x12\x13\n" + "\x0fKEY_UNSPECIFIED\x10\x00\x12\v\n" + "\aGENERAL\x10\x01\x12\v\n" + "\aSTORAGE\x10\x02\x12\x10\n" + - "\fMEMO_RELATED\x10\x03:a\xeaA^\n" + + "\fMEMO_RELATED\x10\x03\x12\b\n" + + "\x04TAGS\x10\x04:a\xeaA^\n" + "\x1cmemos.api.v1/InstanceSetting\x12\x1binstance/settings/{setting}*\x10instanceSettings2\x0finstanceSettingB\a\n" + "\x05value\"U\n" + "\x19GetInstanceSettingRequest\x128\n" + @@ -956,7 +1077,7 @@ func file_api_v1_instance_service_proto_rawDescGZIP() []byte { } var file_api_v1_instance_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_api_v1_instance_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_api_v1_instance_service_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_api_v1_instance_service_proto_goTypes = []any{ (InstanceSetting_Key)(0), // 0: memos.api.v1.InstanceSetting.Key (InstanceSetting_StorageSetting_StorageType)(0), // 1: memos.api.v1.InstanceSetting.StorageSetting.StorageType @@ -968,32 +1089,40 @@ var file_api_v1_instance_service_proto_goTypes = []any{ (*InstanceSetting_GeneralSetting)(nil), // 7: memos.api.v1.InstanceSetting.GeneralSetting (*InstanceSetting_StorageSetting)(nil), // 8: memos.api.v1.InstanceSetting.StorageSetting (*InstanceSetting_MemoRelatedSetting)(nil), // 9: memos.api.v1.InstanceSetting.MemoRelatedSetting - (*InstanceSetting_GeneralSetting_CustomProfile)(nil), // 10: memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile - (*InstanceSetting_StorageSetting_S3Config)(nil), // 11: memos.api.v1.InstanceSetting.StorageSetting.S3Config - (*User)(nil), // 12: memos.api.v1.User - (*fieldmaskpb.FieldMask)(nil), // 13: google.protobuf.FieldMask + (*InstanceSetting_TagMetadata)(nil), // 10: memos.api.v1.InstanceSetting.TagMetadata + (*InstanceSetting_TagsSetting)(nil), // 11: memos.api.v1.InstanceSetting.TagsSetting + (*InstanceSetting_GeneralSetting_CustomProfile)(nil), // 12: memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile + (*InstanceSetting_StorageSetting_S3Config)(nil), // 13: memos.api.v1.InstanceSetting.StorageSetting.S3Config + nil, // 14: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry + (*User)(nil), // 15: memos.api.v1.User + (*fieldmaskpb.FieldMask)(nil), // 16: google.protobuf.FieldMask + (*color.Color)(nil), // 17: google.type.Color } var file_api_v1_instance_service_proto_depIdxs = []int32{ - 12, // 0: memos.api.v1.InstanceProfile.admin:type_name -> memos.api.v1.User + 15, // 0: memos.api.v1.InstanceProfile.admin:type_name -> memos.api.v1.User 7, // 1: memos.api.v1.InstanceSetting.general_setting:type_name -> memos.api.v1.InstanceSetting.GeneralSetting 8, // 2: memos.api.v1.InstanceSetting.storage_setting:type_name -> memos.api.v1.InstanceSetting.StorageSetting 9, // 3: memos.api.v1.InstanceSetting.memo_related_setting:type_name -> memos.api.v1.InstanceSetting.MemoRelatedSetting - 4, // 4: memos.api.v1.UpdateInstanceSettingRequest.setting:type_name -> memos.api.v1.InstanceSetting - 13, // 5: memos.api.v1.UpdateInstanceSettingRequest.update_mask:type_name -> google.protobuf.FieldMask - 10, // 6: memos.api.v1.InstanceSetting.GeneralSetting.custom_profile:type_name -> memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile - 1, // 7: memos.api.v1.InstanceSetting.StorageSetting.storage_type:type_name -> memos.api.v1.InstanceSetting.StorageSetting.StorageType - 11, // 8: memos.api.v1.InstanceSetting.StorageSetting.s3_config:type_name -> memos.api.v1.InstanceSetting.StorageSetting.S3Config - 3, // 9: memos.api.v1.InstanceService.GetInstanceProfile:input_type -> memos.api.v1.GetInstanceProfileRequest - 5, // 10: memos.api.v1.InstanceService.GetInstanceSetting:input_type -> memos.api.v1.GetInstanceSettingRequest - 6, // 11: memos.api.v1.InstanceService.UpdateInstanceSetting:input_type -> memos.api.v1.UpdateInstanceSettingRequest - 2, // 12: memos.api.v1.InstanceService.GetInstanceProfile:output_type -> memos.api.v1.InstanceProfile - 4, // 13: memos.api.v1.InstanceService.GetInstanceSetting:output_type -> memos.api.v1.InstanceSetting - 4, // 14: memos.api.v1.InstanceService.UpdateInstanceSetting:output_type -> memos.api.v1.InstanceSetting - 12, // [12:15] is the sub-list for method output_type - 9, // [9:12] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 11, // 4: memos.api.v1.InstanceSetting.tags_setting:type_name -> memos.api.v1.InstanceSetting.TagsSetting + 4, // 5: memos.api.v1.UpdateInstanceSettingRequest.setting:type_name -> memos.api.v1.InstanceSetting + 16, // 6: memos.api.v1.UpdateInstanceSettingRequest.update_mask:type_name -> google.protobuf.FieldMask + 12, // 7: memos.api.v1.InstanceSetting.GeneralSetting.custom_profile:type_name -> memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile + 1, // 8: memos.api.v1.InstanceSetting.StorageSetting.storage_type:type_name -> memos.api.v1.InstanceSetting.StorageSetting.StorageType + 13, // 9: memos.api.v1.InstanceSetting.StorageSetting.s3_config:type_name -> memos.api.v1.InstanceSetting.StorageSetting.S3Config + 17, // 10: memos.api.v1.InstanceSetting.TagMetadata.background_color:type_name -> google.type.Color + 14, // 11: memos.api.v1.InstanceSetting.TagsSetting.tags:type_name -> memos.api.v1.InstanceSetting.TagsSetting.TagsEntry + 10, // 12: memos.api.v1.InstanceSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.InstanceSetting.TagMetadata + 3, // 13: memos.api.v1.InstanceService.GetInstanceProfile:input_type -> memos.api.v1.GetInstanceProfileRequest + 5, // 14: memos.api.v1.InstanceService.GetInstanceSetting:input_type -> memos.api.v1.GetInstanceSettingRequest + 6, // 15: memos.api.v1.InstanceService.UpdateInstanceSetting:input_type -> memos.api.v1.UpdateInstanceSettingRequest + 2, // 16: memos.api.v1.InstanceService.GetInstanceProfile:output_type -> memos.api.v1.InstanceProfile + 4, // 17: memos.api.v1.InstanceService.GetInstanceSetting:output_type -> memos.api.v1.InstanceSetting + 4, // 18: memos.api.v1.InstanceService.UpdateInstanceSetting:output_type -> memos.api.v1.InstanceSetting + 16, // [16:19] is the sub-list for method output_type + 13, // [13:16] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_api_v1_instance_service_proto_init() } @@ -1006,6 +1135,7 @@ func file_api_v1_instance_service_proto_init() { (*InstanceSetting_GeneralSetting_)(nil), (*InstanceSetting_StorageSetting_)(nil), (*InstanceSetting_MemoRelatedSetting_)(nil), + (*InstanceSetting_TagsSetting_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1013,7 +1143,7 @@ func file_api_v1_instance_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_instance_service_proto_rawDesc), len(file_api_v1_instance_service_proto_rawDesc)), NumEnums: 2, - NumMessages: 10, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v1/user_service.pb.go b/proto/gen/api/v1/user_service.pb.go index c15014da6..bb210e8ab 100644 --- a/proto/gen/api/v1/user_service.pb.go +++ b/proto/gen/api/v1/user_service.pb.go @@ -8,7 +8,6 @@ package apiv1 import ( _ "google.golang.org/genproto/googleapis/api/annotations" - color "google.golang.org/genproto/googleapis/type/color" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -87,8 +86,6 @@ const ( UserSetting_GENERAL UserSetting_Key = 1 // WEBHOOKS is the key for user webhooks. UserSetting_WEBHOOKS UserSetting_Key = 4 - // TAGS is the key for user tag metadata. - UserSetting_TAGS UserSetting_Key = 5 ) // Enum value maps for UserSetting_Key. @@ -97,13 +94,11 @@ var ( 0: "KEY_UNSPECIFIED", 1: "GENERAL", 4: "WEBHOOKS", - 5: "TAGS", } UserSetting_Key_value = map[string]int32{ "KEY_UNSPECIFIED": 0, "GENERAL": 1, "WEBHOOKS": 4, - "TAGS": 5, } ) @@ -991,7 +986,6 @@ type UserSetting struct { // // *UserSetting_GeneralSetting_ // *UserSetting_WebhooksSetting_ - // *UserSetting_TagsSetting_ Value isUserSetting_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1059,15 +1053,6 @@ func (x *UserSetting) GetWebhooksSetting() *UserSetting_WebhooksSetting { return nil } -func (x *UserSetting) GetTagsSetting() *UserSetting_TagsSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_TagsSetting_); ok { - return x.TagsSetting - } - } - return nil -} - type isUserSetting_Value interface { isUserSetting_Value() } @@ -1080,16 +1065,10 @@ type UserSetting_WebhooksSetting_ struct { WebhooksSetting *UserSetting_WebhooksSetting `protobuf:"bytes,5,opt,name=webhooks_setting,json=webhooksSetting,proto3,oneof"` } -type UserSetting_TagsSetting_ struct { - TagsSetting *UserSetting_TagsSetting `protobuf:"bytes,6,opt,name=tags_setting,json=tagsSetting,proto3,oneof"` -} - func (*UserSetting_GeneralSetting_) isUserSetting_Value() {} func (*UserSetting_WebhooksSetting_) isUserSetting_Value() {} -func (*UserSetting_TagsSetting_) isUserSetting_Value() {} - type GetUserSettingRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Required. The resource name of the user setting. @@ -2542,97 +2521,6 @@ func (x *UserSetting_WebhooksSetting) GetWebhooks() []*UserWebhook { return nil } -// Metadata for a tag. -type UserSetting_TagMetadata struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Background color for the tag label. - BackgroundColor *color.Color `protobuf:"bytes,1,opt,name=background_color,json=backgroundColor,proto3" json:"background_color,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UserSetting_TagMetadata) Reset() { - *x = UserSetting_TagMetadata{} - mi := &file_api_v1_user_service_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UserSetting_TagMetadata) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserSetting_TagMetadata) ProtoMessage() {} - -func (x *UserSetting_TagMetadata) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[37] - 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 UserSetting_TagMetadata.ProtoReflect.Descriptor instead. -func (*UserSetting_TagMetadata) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 2} -} - -func (x *UserSetting_TagMetadata) GetBackgroundColor() *color.Color { - if x != nil { - return x.BackgroundColor - } - return nil -} - -// User tag metadata configuration. -type UserSetting_TagsSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - Tags map[string]*UserSetting_TagMetadata `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UserSetting_TagsSetting) Reset() { - *x = UserSetting_TagsSetting{} - mi := &file_api_v1_user_service_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UserSetting_TagsSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserSetting_TagsSetting) ProtoMessage() {} - -func (x *UserSetting_TagsSetting) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[38] - 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 UserSetting_TagsSetting.ProtoReflect.Descriptor instead. -func (*UserSetting_TagsSetting) Descriptor() ([]byte, []int) { - return file_api_v1_user_service_proto_rawDescGZIP(), []int{11, 3} -} - -func (x *UserSetting_TagsSetting) GetTags() map[string]*UserSetting_TagMetadata { - if x != nil { - return x.Tags - } - return nil -} - type UserNotification_MemoCommentPayload struct { state protoimpl.MessageState `protogen:"open.v1"` // The memo name of comment. @@ -2647,7 +2535,7 @@ type UserNotification_MemoCommentPayload struct { func (x *UserNotification_MemoCommentPayload) Reset() { *x = UserNotification_MemoCommentPayload{} - mi := &file_api_v1_user_service_proto_msgTypes[40] + mi := &file_api_v1_user_service_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2659,7 +2547,7 @@ func (x *UserNotification_MemoCommentPayload) String() string { func (*UserNotification_MemoCommentPayload) ProtoMessage() {} func (x *UserNotification_MemoCommentPayload) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_user_service_proto_msgTypes[40] + mi := &file_api_v1_user_service_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2693,7 +2581,7 @@ var File_api_v1_user_service_proto protoreflect.FileDescriptor const file_api_v1_user_service_proto_rawDesc = "" + "\n" + - "\x19api/v1/user_service.proto\x12\fmemos.api.v1\x1a\x13api/v1/common.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17google/type/color.proto\"\xc1\x04\n" + + "\x19api/v1/user_service.proto\x12\fmemos.api.v1\x1a\x13api/v1/common.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc1\x04\n" + "\x04User\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x120\n" + "\x04role\x18\x02 \x01(\x0e2\x17.memos.api.v1.User.RoleB\x03\xe0A\x02R\x04role\x12\x1f\n" + @@ -2770,30 +2658,21 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\x11memos.api.v1/UserR\x04name\"\x19\n" + "\x17ListAllUserStatsRequest\"I\n" + "\x18ListAllUserStatsResponse\x12-\n" + - "\x05stats\x18\x01 \x03(\v2\x17.memos.api.v1.UserStatsR\x05stats\"\x89\a\n" + + "\x05stats\x18\x01 \x03(\v2\x17.memos.api.v1.UserStatsR\x05stats\"\xb0\x04\n" + "\vUserSetting\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12S\n" + "\x0fgeneral_setting\x18\x02 \x01(\v2(.memos.api.v1.UserSetting.GeneralSettingH\x00R\x0egeneralSetting\x12V\n" + - "\x10webhooks_setting\x18\x05 \x01(\v2).memos.api.v1.UserSetting.WebhooksSettingH\x00R\x0fwebhooksSetting\x12J\n" + - "\ftags_setting\x18\x06 \x01(\v2%.memos.api.v1.UserSetting.TagsSettingH\x00R\vtagsSetting\x1av\n" + + "\x10webhooks_setting\x18\x05 \x01(\v2).memos.api.v1.UserSetting.WebhooksSettingH\x00R\x0fwebhooksSetting\x1av\n" + "\x0eGeneralSetting\x12\x1b\n" + "\x06locale\x18\x01 \x01(\tB\x03\xe0A\x01R\x06locale\x12,\n" + "\x0fmemo_visibility\x18\x03 \x01(\tB\x03\xe0A\x01R\x0ememoVisibility\x12\x19\n" + "\x05theme\x18\x04 \x01(\tB\x03\xe0A\x01R\x05theme\x1aH\n" + "\x0fWebhooksSetting\x125\n" + - "\bwebhooks\x18\x01 \x03(\v2\x19.memos.api.v1.UserWebhookR\bwebhooks\x1aL\n" + - "\vTagMetadata\x12=\n" + - "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\x1a\xb2\x01\n" + - "\vTagsSetting\x12C\n" + - "\x04tags\x18\x01 \x03(\v2/.memos.api.v1.UserSetting.TagsSetting.TagsEntryR\x04tags\x1a^\n" + - "\tTagsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12;\n" + - "\x05value\x18\x02 \x01(\v2%.memos.api.v1.UserSetting.TagMetadataR\x05value:\x028\x01\"?\n" + + "\bwebhooks\x18\x01 \x03(\v2\x19.memos.api.v1.UserWebhookR\bwebhooks\"5\n" + "\x03Key\x12\x13\n" + "\x0fKEY_UNSPECIFIED\x10\x00\x12\v\n" + "\aGENERAL\x10\x01\x12\f\n" + - "\bWEBHOOKS\x10\x04\x12\b\n" + - "\x04TAGS\x10\x05:Y\xeaAV\n" + + "\bWEBHOOKS\x10\x04:Y\xeaAV\n" + "\x18memos.api.v1/UserSetting\x12\x1fusers/{user}/settings/{setting}*\fuserSettings2\vuserSettingB\a\n" + "\x05value\"M\n" + "\x15GetUserSettingRequest\x124\n" + @@ -2945,7 +2824,7 @@ func file_api_v1_user_service_proto_rawDescGZIP() []byte { } var file_api_v1_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_api_v1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 38) var file_api_v1_user_service_proto_goTypes = []any{ (User_Role)(0), // 0: memos.api.v1.User.Role (UserSetting_Key)(0), // 1: memos.api.v1.UserSetting.Key @@ -2988,103 +2867,95 @@ var file_api_v1_user_service_proto_goTypes = []any{ (*UserStats_MemoTypeStats)(nil), // 38: memos.api.v1.UserStats.MemoTypeStats (*UserSetting_GeneralSetting)(nil), // 39: memos.api.v1.UserSetting.GeneralSetting (*UserSetting_WebhooksSetting)(nil), // 40: memos.api.v1.UserSetting.WebhooksSetting - (*UserSetting_TagMetadata)(nil), // 41: memos.api.v1.UserSetting.TagMetadata - (*UserSetting_TagsSetting)(nil), // 42: memos.api.v1.UserSetting.TagsSetting - nil, // 43: memos.api.v1.UserSetting.TagsSetting.TagsEntry - (*UserNotification_MemoCommentPayload)(nil), // 44: memos.api.v1.UserNotification.MemoCommentPayload - (State)(0), // 45: memos.api.v1.State - (*timestamppb.Timestamp)(nil), // 46: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 47: google.protobuf.FieldMask - (*color.Color)(nil), // 48: google.type.Color - (*emptypb.Empty)(nil), // 49: google.protobuf.Empty + (*UserNotification_MemoCommentPayload)(nil), // 41: memos.api.v1.UserNotification.MemoCommentPayload + (State)(0), // 42: memos.api.v1.State + (*timestamppb.Timestamp)(nil), // 43: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 44: google.protobuf.FieldMask + (*emptypb.Empty)(nil), // 45: google.protobuf.Empty } var file_api_v1_user_service_proto_depIdxs = []int32{ 0, // 0: memos.api.v1.User.role:type_name -> memos.api.v1.User.Role - 45, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State - 46, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp - 46, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp + 42, // 1: memos.api.v1.User.state:type_name -> memos.api.v1.State + 43, // 2: memos.api.v1.User.create_time:type_name -> google.protobuf.Timestamp + 43, // 3: memos.api.v1.User.update_time:type_name -> google.protobuf.Timestamp 4, // 4: memos.api.v1.ListUsersResponse.users:type_name -> memos.api.v1.User - 47, // 5: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask + 44, // 5: memos.api.v1.GetUserRequest.read_mask:type_name -> google.protobuf.FieldMask 4, // 6: memos.api.v1.CreateUserRequest.user:type_name -> memos.api.v1.User 4, // 7: memos.api.v1.UpdateUserRequest.user:type_name -> memos.api.v1.User - 47, // 8: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask - 46, // 9: memos.api.v1.UserStats.memo_display_timestamps:type_name -> google.protobuf.Timestamp + 44, // 8: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask + 43, // 9: memos.api.v1.UserStats.memo_display_timestamps:type_name -> google.protobuf.Timestamp 38, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats 37, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry 11, // 12: memos.api.v1.ListAllUserStatsResponse.stats:type_name -> memos.api.v1.UserStats 39, // 13: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting 40, // 14: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting - 42, // 15: memos.api.v1.UserSetting.tags_setting:type_name -> memos.api.v1.UserSetting.TagsSetting - 15, // 16: memos.api.v1.UpdateUserSettingRequest.setting:type_name -> memos.api.v1.UserSetting - 47, // 17: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask - 15, // 18: memos.api.v1.ListUserSettingsResponse.settings:type_name -> memos.api.v1.UserSetting - 46, // 19: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp - 46, // 20: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp - 46, // 21: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp - 20, // 22: memos.api.v1.ListPersonalAccessTokensResponse.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken - 20, // 23: memos.api.v1.CreatePersonalAccessTokenResponse.personal_access_token:type_name -> memos.api.v1.PersonalAccessToken - 46, // 24: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp - 46, // 25: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp - 26, // 26: memos.api.v1.ListUserWebhooksResponse.webhooks:type_name -> memos.api.v1.UserWebhook - 26, // 27: memos.api.v1.CreateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook - 26, // 28: memos.api.v1.UpdateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook - 47, // 29: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask - 2, // 30: memos.api.v1.UserNotification.status:type_name -> memos.api.v1.UserNotification.Status - 46, // 31: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp - 3, // 32: memos.api.v1.UserNotification.type:type_name -> memos.api.v1.UserNotification.Type - 44, // 33: memos.api.v1.UserNotification.memo_comment:type_name -> memos.api.v1.UserNotification.MemoCommentPayload - 32, // 34: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification - 32, // 35: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification - 47, // 36: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask - 26, // 37: memos.api.v1.UserSetting.WebhooksSetting.webhooks:type_name -> memos.api.v1.UserWebhook - 48, // 38: memos.api.v1.UserSetting.TagMetadata.background_color:type_name -> google.type.Color - 43, // 39: memos.api.v1.UserSetting.TagsSetting.tags:type_name -> memos.api.v1.UserSetting.TagsSetting.TagsEntry - 41, // 40: memos.api.v1.UserSetting.TagsSetting.TagsEntry.value:type_name -> memos.api.v1.UserSetting.TagMetadata - 5, // 41: memos.api.v1.UserService.ListUsers:input_type -> memos.api.v1.ListUsersRequest - 7, // 42: memos.api.v1.UserService.GetUser:input_type -> memos.api.v1.GetUserRequest - 8, // 43: memos.api.v1.UserService.CreateUser:input_type -> memos.api.v1.CreateUserRequest - 9, // 44: memos.api.v1.UserService.UpdateUser:input_type -> memos.api.v1.UpdateUserRequest - 10, // 45: memos.api.v1.UserService.DeleteUser:input_type -> memos.api.v1.DeleteUserRequest - 13, // 46: memos.api.v1.UserService.ListAllUserStats:input_type -> memos.api.v1.ListAllUserStatsRequest - 12, // 47: memos.api.v1.UserService.GetUserStats:input_type -> memos.api.v1.GetUserStatsRequest - 16, // 48: memos.api.v1.UserService.GetUserSetting:input_type -> memos.api.v1.GetUserSettingRequest - 17, // 49: memos.api.v1.UserService.UpdateUserSetting:input_type -> memos.api.v1.UpdateUserSettingRequest - 18, // 50: memos.api.v1.UserService.ListUserSettings:input_type -> memos.api.v1.ListUserSettingsRequest - 21, // 51: memos.api.v1.UserService.ListPersonalAccessTokens:input_type -> memos.api.v1.ListPersonalAccessTokensRequest - 23, // 52: memos.api.v1.UserService.CreatePersonalAccessToken:input_type -> memos.api.v1.CreatePersonalAccessTokenRequest - 25, // 53: memos.api.v1.UserService.DeletePersonalAccessToken:input_type -> memos.api.v1.DeletePersonalAccessTokenRequest - 27, // 54: memos.api.v1.UserService.ListUserWebhooks:input_type -> memos.api.v1.ListUserWebhooksRequest - 29, // 55: memos.api.v1.UserService.CreateUserWebhook:input_type -> memos.api.v1.CreateUserWebhookRequest - 30, // 56: memos.api.v1.UserService.UpdateUserWebhook:input_type -> memos.api.v1.UpdateUserWebhookRequest - 31, // 57: memos.api.v1.UserService.DeleteUserWebhook:input_type -> memos.api.v1.DeleteUserWebhookRequest - 33, // 58: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest - 35, // 59: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest - 36, // 60: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest - 6, // 61: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse - 4, // 62: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User - 4, // 63: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User - 4, // 64: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User - 49, // 65: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty - 14, // 66: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse - 11, // 67: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats - 15, // 68: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting - 15, // 69: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting - 19, // 70: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse - 22, // 71: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse - 24, // 72: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse - 49, // 73: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty - 28, // 74: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse - 26, // 75: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook - 26, // 76: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook - 49, // 77: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty - 34, // 78: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse - 32, // 79: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification - 49, // 80: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty - 61, // [61:81] is the sub-list for method output_type - 41, // [41:61] is the sub-list for method input_type - 41, // [41:41] is the sub-list for extension type_name - 41, // [41:41] is the sub-list for extension extendee - 0, // [0:41] is the sub-list for field type_name + 15, // 15: memos.api.v1.UpdateUserSettingRequest.setting:type_name -> memos.api.v1.UserSetting + 44, // 16: memos.api.v1.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask + 15, // 17: memos.api.v1.ListUserSettingsResponse.settings:type_name -> memos.api.v1.UserSetting + 43, // 18: memos.api.v1.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp + 43, // 19: memos.api.v1.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp + 43, // 20: memos.api.v1.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp + 20, // 21: memos.api.v1.ListPersonalAccessTokensResponse.personal_access_tokens:type_name -> memos.api.v1.PersonalAccessToken + 20, // 22: memos.api.v1.CreatePersonalAccessTokenResponse.personal_access_token:type_name -> memos.api.v1.PersonalAccessToken + 43, // 23: memos.api.v1.UserWebhook.create_time:type_name -> google.protobuf.Timestamp + 43, // 24: memos.api.v1.UserWebhook.update_time:type_name -> google.protobuf.Timestamp + 26, // 25: memos.api.v1.ListUserWebhooksResponse.webhooks:type_name -> memos.api.v1.UserWebhook + 26, // 26: memos.api.v1.CreateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook + 26, // 27: memos.api.v1.UpdateUserWebhookRequest.webhook:type_name -> memos.api.v1.UserWebhook + 44, // 28: memos.api.v1.UpdateUserWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask + 2, // 29: memos.api.v1.UserNotification.status:type_name -> memos.api.v1.UserNotification.Status + 43, // 30: memos.api.v1.UserNotification.create_time:type_name -> google.protobuf.Timestamp + 3, // 31: memos.api.v1.UserNotification.type:type_name -> memos.api.v1.UserNotification.Type + 41, // 32: memos.api.v1.UserNotification.memo_comment:type_name -> memos.api.v1.UserNotification.MemoCommentPayload + 32, // 33: memos.api.v1.ListUserNotificationsResponse.notifications:type_name -> memos.api.v1.UserNotification + 32, // 34: memos.api.v1.UpdateUserNotificationRequest.notification:type_name -> memos.api.v1.UserNotification + 44, // 35: memos.api.v1.UpdateUserNotificationRequest.update_mask:type_name -> google.protobuf.FieldMask + 26, // 36: memos.api.v1.UserSetting.WebhooksSetting.webhooks:type_name -> memos.api.v1.UserWebhook + 5, // 37: memos.api.v1.UserService.ListUsers:input_type -> memos.api.v1.ListUsersRequest + 7, // 38: memos.api.v1.UserService.GetUser:input_type -> memos.api.v1.GetUserRequest + 8, // 39: memos.api.v1.UserService.CreateUser:input_type -> memos.api.v1.CreateUserRequest + 9, // 40: memos.api.v1.UserService.UpdateUser:input_type -> memos.api.v1.UpdateUserRequest + 10, // 41: memos.api.v1.UserService.DeleteUser:input_type -> memos.api.v1.DeleteUserRequest + 13, // 42: memos.api.v1.UserService.ListAllUserStats:input_type -> memos.api.v1.ListAllUserStatsRequest + 12, // 43: memos.api.v1.UserService.GetUserStats:input_type -> memos.api.v1.GetUserStatsRequest + 16, // 44: memos.api.v1.UserService.GetUserSetting:input_type -> memos.api.v1.GetUserSettingRequest + 17, // 45: memos.api.v1.UserService.UpdateUserSetting:input_type -> memos.api.v1.UpdateUserSettingRequest + 18, // 46: memos.api.v1.UserService.ListUserSettings:input_type -> memos.api.v1.ListUserSettingsRequest + 21, // 47: memos.api.v1.UserService.ListPersonalAccessTokens:input_type -> memos.api.v1.ListPersonalAccessTokensRequest + 23, // 48: memos.api.v1.UserService.CreatePersonalAccessToken:input_type -> memos.api.v1.CreatePersonalAccessTokenRequest + 25, // 49: memos.api.v1.UserService.DeletePersonalAccessToken:input_type -> memos.api.v1.DeletePersonalAccessTokenRequest + 27, // 50: memos.api.v1.UserService.ListUserWebhooks:input_type -> memos.api.v1.ListUserWebhooksRequest + 29, // 51: memos.api.v1.UserService.CreateUserWebhook:input_type -> memos.api.v1.CreateUserWebhookRequest + 30, // 52: memos.api.v1.UserService.UpdateUserWebhook:input_type -> memos.api.v1.UpdateUserWebhookRequest + 31, // 53: memos.api.v1.UserService.DeleteUserWebhook:input_type -> memos.api.v1.DeleteUserWebhookRequest + 33, // 54: memos.api.v1.UserService.ListUserNotifications:input_type -> memos.api.v1.ListUserNotificationsRequest + 35, // 55: memos.api.v1.UserService.UpdateUserNotification:input_type -> memos.api.v1.UpdateUserNotificationRequest + 36, // 56: memos.api.v1.UserService.DeleteUserNotification:input_type -> memos.api.v1.DeleteUserNotificationRequest + 6, // 57: memos.api.v1.UserService.ListUsers:output_type -> memos.api.v1.ListUsersResponse + 4, // 58: memos.api.v1.UserService.GetUser:output_type -> memos.api.v1.User + 4, // 59: memos.api.v1.UserService.CreateUser:output_type -> memos.api.v1.User + 4, // 60: memos.api.v1.UserService.UpdateUser:output_type -> memos.api.v1.User + 45, // 61: memos.api.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty + 14, // 62: memos.api.v1.UserService.ListAllUserStats:output_type -> memos.api.v1.ListAllUserStatsResponse + 11, // 63: memos.api.v1.UserService.GetUserStats:output_type -> memos.api.v1.UserStats + 15, // 64: memos.api.v1.UserService.GetUserSetting:output_type -> memos.api.v1.UserSetting + 15, // 65: memos.api.v1.UserService.UpdateUserSetting:output_type -> memos.api.v1.UserSetting + 19, // 66: memos.api.v1.UserService.ListUserSettings:output_type -> memos.api.v1.ListUserSettingsResponse + 22, // 67: memos.api.v1.UserService.ListPersonalAccessTokens:output_type -> memos.api.v1.ListPersonalAccessTokensResponse + 24, // 68: memos.api.v1.UserService.CreatePersonalAccessToken:output_type -> memos.api.v1.CreatePersonalAccessTokenResponse + 45, // 69: memos.api.v1.UserService.DeletePersonalAccessToken:output_type -> google.protobuf.Empty + 28, // 70: memos.api.v1.UserService.ListUserWebhooks:output_type -> memos.api.v1.ListUserWebhooksResponse + 26, // 71: memos.api.v1.UserService.CreateUserWebhook:output_type -> memos.api.v1.UserWebhook + 26, // 72: memos.api.v1.UserService.UpdateUserWebhook:output_type -> memos.api.v1.UserWebhook + 45, // 73: memos.api.v1.UserService.DeleteUserWebhook:output_type -> google.protobuf.Empty + 34, // 74: memos.api.v1.UserService.ListUserNotifications:output_type -> memos.api.v1.ListUserNotificationsResponse + 32, // 75: memos.api.v1.UserService.UpdateUserNotification:output_type -> memos.api.v1.UserNotification + 45, // 76: memos.api.v1.UserService.DeleteUserNotification:output_type -> google.protobuf.Empty + 57, // [57:77] is the sub-list for method output_type + 37, // [37:57] is the sub-list for method input_type + 37, // [37:37] is the sub-list for extension type_name + 37, // [37:37] is the sub-list for extension extendee + 0, // [0:37] is the sub-list for field type_name } func init() { file_api_v1_user_service_proto_init() } @@ -3096,7 +2967,6 @@ func file_api_v1_user_service_proto_init() { file_api_v1_user_service_proto_msgTypes[11].OneofWrappers = []any{ (*UserSetting_GeneralSetting_)(nil), (*UserSetting_WebhooksSetting_)(nil), - (*UserSetting_TagsSetting_)(nil), } file_api_v1_user_service_proto_msgTypes[28].OneofWrappers = []any{ (*UserNotification_MemoComment)(nil), @@ -3107,7 +2977,7 @@ func file_api_v1_user_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_user_service_proto_rawDesc), len(file_api_v1_user_service_proto_rawDesc)), NumEnums: 4, - NumMessages: 41, + NumMessages: 38, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index dac7f2eac..5dd207279 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -2190,6 +2190,8 @@ components: $ref: '#/components/schemas/InstanceSetting_StorageSetting' memoRelatedSetting: $ref: '#/components/schemas/InstanceSetting_MemoRelatedSetting' + tagsSetting: + $ref: '#/components/schemas/InstanceSetting_TagsSetting' description: An instance setting resource. InstanceSetting_GeneralSetting: type: object @@ -2271,6 +2273,22 @@ components: - $ref: '#/components/schemas/StorageSetting_S3Config' description: The S3 config. description: Storage configuration settings for instance attachments. + InstanceSetting_TagMetadata: + type: object + properties: + backgroundColor: + allOf: + - $ref: '#/components/schemas/Color' + description: Background color for the tag label. + description: Metadata for a tag. + InstanceSetting_TagsSetting: + type: object + properties: + tags: + type: object + additionalProperties: + $ref: '#/components/schemas/InstanceSetting_TagMetadata' + description: Tag metadata configuration. ListAllUserStatsResponse: type: object properties: @@ -2986,8 +3004,6 @@ components: $ref: '#/components/schemas/UserSetting_GeneralSetting' webhooksSetting: $ref: '#/components/schemas/UserSetting_WebhooksSetting' - tagsSetting: - $ref: '#/components/schemas/UserSetting_TagsSetting' description: User settings message UserSetting_GeneralSetting: type: object @@ -3005,22 +3021,6 @@ components: This references a CSS file in the web/public/themes/ directory. If not set, the default theme will be used. description: General user settings configuration. - UserSetting_TagMetadata: - type: object - properties: - backgroundColor: - allOf: - - $ref: '#/components/schemas/Color' - description: Background color for the tag label. - description: Metadata for a tag. - UserSetting_TagsSetting: - type: object - properties: - tags: - type: object - additionalProperties: - $ref: '#/components/schemas/UserSetting_TagMetadata' - description: User tag metadata configuration. UserSetting_WebhooksSetting: type: object properties: diff --git a/proto/gen/store/instance_setting.pb.go b/proto/gen/store/instance_setting.pb.go index d368e626d..c3a9e325c 100644 --- a/proto/gen/store/instance_setting.pb.go +++ b/proto/gen/store/instance_setting.pb.go @@ -7,6 +7,7 @@ package store import ( + color "google.golang.org/genproto/googleapis/type/color" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -33,6 +34,8 @@ const ( InstanceSettingKey_STORAGE InstanceSettingKey = 3 // MEMO_RELATED is the key for memo related settings. InstanceSettingKey_MEMO_RELATED InstanceSettingKey = 4 + // TAGS is the key for tag metadata. + InstanceSettingKey_TAGS InstanceSettingKey = 5 ) // Enum value maps for InstanceSettingKey. @@ -43,6 +46,7 @@ var ( 2: "GENERAL", 3: "STORAGE", 4: "MEMO_RELATED", + 5: "TAGS", } InstanceSettingKey_value = map[string]int32{ "INSTANCE_SETTING_KEY_UNSPECIFIED": 0, @@ -50,6 +54,7 @@ var ( "GENERAL": 2, "STORAGE": 3, "MEMO_RELATED": 4, + "TAGS": 5, } ) @@ -144,6 +149,7 @@ type InstanceSetting struct { // *InstanceSetting_GeneralSetting // *InstanceSetting_StorageSetting // *InstanceSetting_MemoRelatedSetting + // *InstanceSetting_TagsSetting Value isInstanceSetting_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -229,6 +235,15 @@ func (x *InstanceSetting) GetMemoRelatedSetting() *InstanceMemoRelatedSetting { return nil } +func (x *InstanceSetting) GetTagsSetting() *InstanceTagsSetting { + if x != nil { + if x, ok := x.Value.(*InstanceSetting_TagsSetting); ok { + return x.TagsSetting + } + } + return nil +} + type isInstanceSetting_Value interface { isInstanceSetting_Value() } @@ -249,6 +264,10 @@ type InstanceSetting_MemoRelatedSetting struct { MemoRelatedSetting *InstanceMemoRelatedSetting `protobuf:"bytes,5,opt,name=memo_related_setting,json=memoRelatedSetting,proto3,oneof"` } +type InstanceSetting_TagsSetting struct { + TagsSetting *InstanceTagsSetting `protobuf:"bytes,6,opt,name=tags_setting,json=tagsSetting,proto3,oneof"` +} + func (*InstanceSetting_BasicSetting) isInstanceSetting_Value() {} func (*InstanceSetting_GeneralSetting) isInstanceSetting_Value() {} @@ -257,6 +276,8 @@ func (*InstanceSetting_StorageSetting) isInstanceSetting_Value() {} func (*InstanceSetting_MemoRelatedSetting) isInstanceSetting_Value() {} +func (*InstanceSetting_TagsSetting) isInstanceSetting_Value() {} + type InstanceBasicSetting struct { state protoimpl.MessageState `protogen:"open.v1"` // The secret key for instance. Mainly used for session management. @@ -720,17 +741,107 @@ func (x *InstanceMemoRelatedSetting) GetReactions() []string { return nil } +type InstanceTagMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Background color for the tag label. + BackgroundColor *color.Color `protobuf:"bytes,1,opt,name=background_color,json=backgroundColor,proto3" json:"background_color,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InstanceTagMetadata) Reset() { + *x = InstanceTagMetadata{} + mi := &file_store_instance_setting_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InstanceTagMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstanceTagMetadata) ProtoMessage() {} + +func (x *InstanceTagMetadata) ProtoReflect() protoreflect.Message { + mi := &file_store_instance_setting_proto_msgTypes[7] + 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 InstanceTagMetadata.ProtoReflect.Descriptor instead. +func (*InstanceTagMetadata) Descriptor() ([]byte, []int) { + return file_store_instance_setting_proto_rawDescGZIP(), []int{7} +} + +func (x *InstanceTagMetadata) GetBackgroundColor() *color.Color { + if x != nil { + return x.BackgroundColor + } + return nil +} + +type InstanceTagsSetting struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tags map[string]*InstanceTagMetadata `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InstanceTagsSetting) Reset() { + *x = InstanceTagsSetting{} + mi := &file_store_instance_setting_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InstanceTagsSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstanceTagsSetting) ProtoMessage() {} + +func (x *InstanceTagsSetting) ProtoReflect() protoreflect.Message { + mi := &file_store_instance_setting_proto_msgTypes[8] + 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 InstanceTagsSetting.ProtoReflect.Descriptor instead. +func (*InstanceTagsSetting) Descriptor() ([]byte, []int) { + return file_store_instance_setting_proto_rawDescGZIP(), []int{8} +} + +func (x *InstanceTagsSetting) GetTags() map[string]*InstanceTagMetadata { + if x != nil { + return x.Tags + } + return nil +} + var File_store_instance_setting_proto protoreflect.FileDescriptor const file_store_instance_setting_proto_rawDesc = "" + "\n" + - "\x1cstore/instance_setting.proto\x12\vmemos.store\"\x94\x03\n" + + "\x1cstore/instance_setting.proto\x12\vmemos.store\x1a\x17google/type/color.proto\"\xdb\x03\n" + "\x0fInstanceSetting\x121\n" + "\x03key\x18\x01 \x01(\x0e2\x1f.memos.store.InstanceSettingKeyR\x03key\x12H\n" + "\rbasic_setting\x18\x02 \x01(\v2!.memos.store.InstanceBasicSettingH\x00R\fbasicSetting\x12N\n" + "\x0fgeneral_setting\x18\x03 \x01(\v2#.memos.store.InstanceGeneralSettingH\x00R\x0egeneralSetting\x12N\n" + "\x0fstorage_setting\x18\x04 \x01(\v2#.memos.store.InstanceStorageSettingH\x00R\x0estorageSetting\x12[\n" + - "\x14memo_related_setting\x18\x05 \x01(\v2'.memos.store.InstanceMemoRelatedSettingH\x00R\x12memoRelatedSettingB\a\n" + + "\x14memo_related_setting\x18\x05 \x01(\v2'.memos.store.InstanceMemoRelatedSettingH\x00R\x12memoRelatedSetting\x12E\n" + + "\ftags_setting\x18\x06 \x01(\v2 .memos.store.InstanceTagsSettingH\x00R\vtagsSettingB\a\n" + "\x05value\"\\\n" + "\x14InstanceBasicSetting\x12\x1d\n" + "\n" + @@ -771,13 +882,21 @@ const file_store_instance_setting_proto_rawDesc = "" + "\x18display_with_update_time\x18\x02 \x01(\bR\x15displayWithUpdateTime\x120\n" + "\x14content_length_limit\x18\x03 \x01(\x05R\x12contentLengthLimit\x127\n" + "\x18enable_double_click_edit\x18\x04 \x01(\bR\x15enableDoubleClickEdit\x12\x1c\n" + - "\treactions\x18\a \x03(\tR\treactions*q\n" + + "\treactions\x18\a \x03(\tR\treactions\"T\n" + + "\x13InstanceTagMetadata\x12=\n" + + "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\"\xb0\x01\n" + + "\x13InstanceTagsSetting\x12>\n" + + "\x04tags\x18\x01 \x03(\v2*.memos.store.InstanceTagsSetting.TagsEntryR\x04tags\x1aY\n" + + "\tTagsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x126\n" + + "\x05value\x18\x02 \x01(\v2 .memos.store.InstanceTagMetadataR\x05value:\x028\x01*{\n" + "\x12InstanceSettingKey\x12$\n" + " INSTANCE_SETTING_KEY_UNSPECIFIED\x10\x00\x12\t\n" + "\x05BASIC\x10\x01\x12\v\n" + "\aGENERAL\x10\x02\x12\v\n" + "\aSTORAGE\x10\x03\x12\x10\n" + - "\fMEMO_RELATED\x10\x04B\x9f\x01\n" + + "\fMEMO_RELATED\x10\x04\x12\b\n" + + "\x04TAGS\x10\x05B\x9f\x01\n" + "\x0fcom.memos.storeB\x14InstanceSettingProtoP\x01Z)github.com/usememos/memos/proto/gen/store\xa2\x02\x03MSX\xaa\x02\vMemos.Store\xca\x02\vMemos\\Store\xe2\x02\x17Memos\\Store\\GPBMetadata\xea\x02\fMemos::Storeb\x06proto3" var ( @@ -793,7 +912,7 @@ func file_store_instance_setting_proto_rawDescGZIP() []byte { } var file_store_instance_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_store_instance_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_store_instance_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_store_instance_setting_proto_goTypes = []any{ (InstanceSettingKey)(0), // 0: memos.store.InstanceSettingKey (InstanceStorageSetting_StorageType)(0), // 1: memos.store.InstanceStorageSetting.StorageType @@ -804,21 +923,29 @@ var file_store_instance_setting_proto_goTypes = []any{ (*InstanceStorageSetting)(nil), // 6: memos.store.InstanceStorageSetting (*StorageS3Config)(nil), // 7: memos.store.StorageS3Config (*InstanceMemoRelatedSetting)(nil), // 8: memos.store.InstanceMemoRelatedSetting + (*InstanceTagMetadata)(nil), // 9: memos.store.InstanceTagMetadata + (*InstanceTagsSetting)(nil), // 10: memos.store.InstanceTagsSetting + nil, // 11: memos.store.InstanceTagsSetting.TagsEntry + (*color.Color)(nil), // 12: google.type.Color } var file_store_instance_setting_proto_depIdxs = []int32{ - 0, // 0: memos.store.InstanceSetting.key:type_name -> memos.store.InstanceSettingKey - 3, // 1: memos.store.InstanceSetting.basic_setting:type_name -> memos.store.InstanceBasicSetting - 4, // 2: memos.store.InstanceSetting.general_setting:type_name -> memos.store.InstanceGeneralSetting - 6, // 3: memos.store.InstanceSetting.storage_setting:type_name -> memos.store.InstanceStorageSetting - 8, // 4: memos.store.InstanceSetting.memo_related_setting:type_name -> memos.store.InstanceMemoRelatedSetting - 5, // 5: memos.store.InstanceGeneralSetting.custom_profile:type_name -> memos.store.InstanceCustomProfile - 1, // 6: memos.store.InstanceStorageSetting.storage_type:type_name -> memos.store.InstanceStorageSetting.StorageType - 7, // 7: memos.store.InstanceStorageSetting.s3_config:type_name -> memos.store.StorageS3Config - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 0, // 0: memos.store.InstanceSetting.key:type_name -> memos.store.InstanceSettingKey + 3, // 1: memos.store.InstanceSetting.basic_setting:type_name -> memos.store.InstanceBasicSetting + 4, // 2: memos.store.InstanceSetting.general_setting:type_name -> memos.store.InstanceGeneralSetting + 6, // 3: memos.store.InstanceSetting.storage_setting:type_name -> memos.store.InstanceStorageSetting + 8, // 4: memos.store.InstanceSetting.memo_related_setting:type_name -> memos.store.InstanceMemoRelatedSetting + 10, // 5: memos.store.InstanceSetting.tags_setting:type_name -> memos.store.InstanceTagsSetting + 5, // 6: memos.store.InstanceGeneralSetting.custom_profile:type_name -> memos.store.InstanceCustomProfile + 1, // 7: memos.store.InstanceStorageSetting.storage_type:type_name -> memos.store.InstanceStorageSetting.StorageType + 7, // 8: memos.store.InstanceStorageSetting.s3_config:type_name -> memos.store.StorageS3Config + 12, // 9: memos.store.InstanceTagMetadata.background_color:type_name -> google.type.Color + 11, // 10: memos.store.InstanceTagsSetting.tags:type_name -> memos.store.InstanceTagsSetting.TagsEntry + 9, // 11: memos.store.InstanceTagsSetting.TagsEntry.value:type_name -> memos.store.InstanceTagMetadata + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_store_instance_setting_proto_init() } @@ -831,6 +958,7 @@ func file_store_instance_setting_proto_init() { (*InstanceSetting_GeneralSetting)(nil), (*InstanceSetting_StorageSetting)(nil), (*InstanceSetting_MemoRelatedSetting)(nil), + (*InstanceSetting_TagsSetting)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -838,7 +966,7 @@ func file_store_instance_setting_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_store_instance_setting_proto_rawDesc), len(file_store_instance_setting_proto_rawDesc)), NumEnums: 2, - NumMessages: 7, + NumMessages: 10, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/gen/store/user_setting.pb.go b/proto/gen/store/user_setting.pb.go index 41181f222..0a6a33104 100644 --- a/proto/gen/store/user_setting.pb.go +++ b/proto/gen/store/user_setting.pb.go @@ -7,7 +7,6 @@ package store import ( - color "google.golang.org/genproto/googleapis/type/color" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" @@ -37,8 +36,6 @@ const ( UserSetting_REFRESH_TOKENS UserSetting_Key = 6 // Personal access tokens for the user. UserSetting_PERSONAL_ACCESS_TOKENS UserSetting_Key = 7 - // Tag metadata for the user. - UserSetting_TAGS UserSetting_Key = 8 ) // Enum value maps for UserSetting_Key. @@ -50,7 +47,6 @@ var ( 5: "WEBHOOKS", 6: "REFRESH_TOKENS", 7: "PERSONAL_ACCESS_TOKENS", - 8: "TAGS", } UserSetting_Key_value = map[string]int32{ "KEY_UNSPECIFIED": 0, @@ -59,7 +55,6 @@ var ( "WEBHOOKS": 5, "REFRESH_TOKENS": 6, "PERSONAL_ACCESS_TOKENS": 7, - "TAGS": 8, } ) @@ -101,7 +96,6 @@ type UserSetting struct { // *UserSetting_Webhooks // *UserSetting_RefreshTokens // *UserSetting_PersonalAccessTokens - // *UserSetting_Tags Value isUserSetting_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -203,15 +197,6 @@ func (x *UserSetting) GetPersonalAccessTokens() *PersonalAccessTokensUserSetting return nil } -func (x *UserSetting) GetTags() *TagsUserSetting { - if x != nil { - if x, ok := x.Value.(*UserSetting_Tags); ok { - return x.Tags - } - } - return nil -} - type isUserSetting_Value interface { isUserSetting_Value() } @@ -236,10 +221,6 @@ type UserSetting_PersonalAccessTokens struct { PersonalAccessTokens *PersonalAccessTokensUserSetting `protobuf:"bytes,9,opt,name=personal_access_tokens,json=personalAccessTokens,proto3,oneof"` } -type UserSetting_Tags struct { - Tags *TagsUserSetting `protobuf:"bytes,10,opt,name=tags,proto3,oneof"` -} - func (*UserSetting_General) isUserSetting_Value() {} func (*UserSetting_Shortcuts) isUserSetting_Value() {} @@ -250,8 +231,6 @@ func (*UserSetting_RefreshTokens) isUserSetting_Value() {} func (*UserSetting_PersonalAccessTokens) isUserSetting_Value() {} -func (*UserSetting_Tags) isUserSetting_Value() {} - type GeneralUserSetting struct { state protoimpl.MessageState `protogen:"open.v1"` // The user's locale. @@ -492,95 +471,6 @@ func (x *WebhooksUserSetting) GetWebhooks() []*WebhooksUserSetting_Webhook { return nil } -type TagMetadata struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Background color for the tag label. - BackgroundColor *color.Color `protobuf:"bytes,1,opt,name=background_color,json=backgroundColor,proto3" json:"background_color,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TagMetadata) Reset() { - *x = TagMetadata{} - mi := &file_store_user_setting_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TagMetadata) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TagMetadata) ProtoMessage() {} - -func (x *TagMetadata) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[6] - 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 TagMetadata.ProtoReflect.Descriptor instead. -func (*TagMetadata) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{6} -} - -func (x *TagMetadata) GetBackgroundColor() *color.Color { - if x != nil { - return x.BackgroundColor - } - return nil -} - -type TagsUserSetting struct { - state protoimpl.MessageState `protogen:"open.v1"` - Tags map[string]*TagMetadata `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TagsUserSetting) Reset() { - *x = TagsUserSetting{} - mi := &file_store_user_setting_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TagsUserSetting) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TagsUserSetting) ProtoMessage() {} - -func (x *TagsUserSetting) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[7] - 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 TagsUserSetting.ProtoReflect.Descriptor instead. -func (*TagsUserSetting) Descriptor() ([]byte, []int) { - return file_store_user_setting_proto_rawDescGZIP(), []int{7} -} - -func (x *TagsUserSetting) GetTags() map[string]*TagMetadata { - if x != nil { - return x.Tags - } - return nil -} - type RefreshTokensUserSetting_RefreshToken struct { state protoimpl.MessageState `protogen:"open.v1"` // Unique identifier (matches 'tid' claim in JWT) @@ -599,7 +489,7 @@ type RefreshTokensUserSetting_RefreshToken struct { func (x *RefreshTokensUserSetting_RefreshToken) Reset() { *x = RefreshTokensUserSetting_RefreshToken{} - mi := &file_store_user_setting_proto_msgTypes[8] + mi := &file_store_user_setting_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -611,7 +501,7 @@ func (x *RefreshTokensUserSetting_RefreshToken) String() string { func (*RefreshTokensUserSetting_RefreshToken) ProtoMessage() {} func (x *RefreshTokensUserSetting_RefreshToken) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[8] + mi := &file_store_user_setting_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -680,7 +570,7 @@ type RefreshTokensUserSetting_ClientInfo struct { func (x *RefreshTokensUserSetting_ClientInfo) Reset() { *x = RefreshTokensUserSetting_ClientInfo{} - mi := &file_store_user_setting_proto_msgTypes[9] + mi := &file_store_user_setting_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -692,7 +582,7 @@ func (x *RefreshTokensUserSetting_ClientInfo) String() string { func (*RefreshTokensUserSetting_ClientInfo) ProtoMessage() {} func (x *RefreshTokensUserSetting_ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[9] + mi := &file_store_user_setting_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -763,7 +653,7 @@ type PersonalAccessTokensUserSetting_PersonalAccessToken struct { func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) Reset() { *x = PersonalAccessTokensUserSetting_PersonalAccessToken{} - mi := &file_store_user_setting_proto_msgTypes[10] + mi := &file_store_user_setting_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -775,7 +665,7 @@ func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) String() string { func (*PersonalAccessTokensUserSetting_PersonalAccessToken) ProtoMessage() {} func (x *PersonalAccessTokensUserSetting_PersonalAccessToken) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[10] + mi := &file_store_user_setting_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -844,7 +734,7 @@ type ShortcutsUserSetting_Shortcut struct { func (x *ShortcutsUserSetting_Shortcut) Reset() { *x = ShortcutsUserSetting_Shortcut{} - mi := &file_store_user_setting_proto_msgTypes[11] + mi := &file_store_user_setting_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -856,7 +746,7 @@ func (x *ShortcutsUserSetting_Shortcut) String() string { func (*ShortcutsUserSetting_Shortcut) ProtoMessage() {} func (x *ShortcutsUserSetting_Shortcut) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[11] + mi := &file_store_user_setting_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -907,7 +797,7 @@ type WebhooksUserSetting_Webhook struct { func (x *WebhooksUserSetting_Webhook) Reset() { *x = WebhooksUserSetting_Webhook{} - mi := &file_store_user_setting_proto_msgTypes[12] + mi := &file_store_user_setting_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -919,7 +809,7 @@ func (x *WebhooksUserSetting_Webhook) String() string { func (*WebhooksUserSetting_Webhook) ProtoMessage() {} func (x *WebhooksUserSetting_Webhook) ProtoReflect() protoreflect.Message { - mi := &file_store_user_setting_proto_msgTypes[12] + mi := &file_store_user_setting_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -960,7 +850,7 @@ var File_store_user_setting_proto protoreflect.FileDescriptor const file_store_user_setting_proto_rawDesc = "" + "\n" + - "\x18store/user_setting.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17google/type/color.proto\"\x89\x05\n" + + "\x18store/user_setting.proto\x12\vmemos.store\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcb\x04\n" + "\vUserSetting\x12\x17\n" + "\auser_id\x18\x01 \x01(\x05R\x06userId\x12.\n" + "\x03key\x18\x02 \x01(\x0e2\x1c.memos.store.UserSetting.KeyR\x03key\x12;\n" + @@ -968,17 +858,14 @@ const file_store_user_setting_proto_rawDesc = "" + "\tshortcuts\x18\x06 \x01(\v2!.memos.store.ShortcutsUserSettingH\x00R\tshortcuts\x12>\n" + "\bwebhooks\x18\a \x01(\v2 .memos.store.WebhooksUserSettingH\x00R\bwebhooks\x12N\n" + "\x0erefresh_tokens\x18\b \x01(\v2%.memos.store.RefreshTokensUserSettingH\x00R\rrefreshTokens\x12d\n" + - "\x16personal_access_tokens\x18\t \x01(\v2,.memos.store.PersonalAccessTokensUserSettingH\x00R\x14personalAccessTokens\x122\n" + - "\x04tags\x18\n" + - " \x01(\v2\x1c.memos.store.TagsUserSettingH\x00R\x04tags\"~\n" + + "\x16personal_access_tokens\x18\t \x01(\v2,.memos.store.PersonalAccessTokensUserSettingH\x00R\x14personalAccessTokens\"t\n" + "\x03Key\x12\x13\n" + "\x0fKEY_UNSPECIFIED\x10\x00\x12\v\n" + "\aGENERAL\x10\x01\x12\r\n" + "\tSHORTCUTS\x10\x04\x12\f\n" + "\bWEBHOOKS\x10\x05\x12\x12\n" + "\x0eREFRESH_TOKENS\x10\x06\x12\x1a\n" + - "\x16PERSONAL_ACCESS_TOKENS\x10\a\x12\b\n" + - "\x04TAGS\x10\bB\a\n" + + "\x16PERSONAL_ACCESS_TOKENS\x10\aB\a\n" + "\x05value\"k\n" + "\x12GeneralUserSetting\x12\x16\n" + "\x06locale\x18\x01 \x01(\tR\x06locale\x12'\n" + @@ -1029,14 +916,7 @@ const file_store_user_setting_proto_rawDesc = "" + "\aWebhook\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + "\x05title\x18\x02 \x01(\tR\x05title\x12\x10\n" + - "\x03url\x18\x03 \x01(\tR\x03url\"L\n" + - "\vTagMetadata\x12=\n" + - "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\"\xa0\x01\n" + - "\x0fTagsUserSetting\x12:\n" + - "\x04tags\x18\x01 \x03(\v2&.memos.store.TagsUserSetting.TagsEntryR\x04tags\x1aQ\n" + - "\tTagsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12.\n" + - "\x05value\x18\x02 \x01(\v2\x18.memos.store.TagMetadataR\x05value:\x028\x01B\x9b\x01\n" + + "\x03url\x18\x03 \x01(\tR\x03urlB\x9b\x01\n" + "\x0fcom.memos.storeB\x10UserSettingProtoP\x01Z)github.com/usememos/memos/proto/gen/store\xa2\x02\x03MSX\xaa\x02\vMemos.Store\xca\x02\vMemos\\Store\xe2\x02\x17Memos\\Store\\GPBMetadata\xea\x02\fMemos::Storeb\x06proto3" var ( @@ -1052,7 +932,7 @@ func file_store_user_setting_proto_rawDescGZIP() []byte { } var file_store_user_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_store_user_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_store_user_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_store_user_setting_proto_goTypes = []any{ (UserSetting_Key)(0), // 0: memos.store.UserSetting.Key (*UserSetting)(nil), // 1: memos.store.UserSetting @@ -1061,16 +941,12 @@ var file_store_user_setting_proto_goTypes = []any{ (*PersonalAccessTokensUserSetting)(nil), // 4: memos.store.PersonalAccessTokensUserSetting (*ShortcutsUserSetting)(nil), // 5: memos.store.ShortcutsUserSetting (*WebhooksUserSetting)(nil), // 6: memos.store.WebhooksUserSetting - (*TagMetadata)(nil), // 7: memos.store.TagMetadata - (*TagsUserSetting)(nil), // 8: memos.store.TagsUserSetting - (*RefreshTokensUserSetting_RefreshToken)(nil), // 9: memos.store.RefreshTokensUserSetting.RefreshToken - (*RefreshTokensUserSetting_ClientInfo)(nil), // 10: memos.store.RefreshTokensUserSetting.ClientInfo - (*PersonalAccessTokensUserSetting_PersonalAccessToken)(nil), // 11: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken - (*ShortcutsUserSetting_Shortcut)(nil), // 12: memos.store.ShortcutsUserSetting.Shortcut - (*WebhooksUserSetting_Webhook)(nil), // 13: memos.store.WebhooksUserSetting.Webhook - nil, // 14: memos.store.TagsUserSetting.TagsEntry - (*color.Color)(nil), // 15: google.type.Color - (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*RefreshTokensUserSetting_RefreshToken)(nil), // 7: memos.store.RefreshTokensUserSetting.RefreshToken + (*RefreshTokensUserSetting_ClientInfo)(nil), // 8: memos.store.RefreshTokensUserSetting.ClientInfo + (*PersonalAccessTokensUserSetting_PersonalAccessToken)(nil), // 9: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken + (*ShortcutsUserSetting_Shortcut)(nil), // 10: memos.store.ShortcutsUserSetting.Shortcut + (*WebhooksUserSetting_Webhook)(nil), // 11: memos.store.WebhooksUserSetting.Webhook + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp } var file_store_user_setting_proto_depIdxs = []int32{ 0, // 0: memos.store.UserSetting.key:type_name -> memos.store.UserSetting.Key @@ -1079,25 +955,21 @@ var file_store_user_setting_proto_depIdxs = []int32{ 6, // 3: memos.store.UserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting 3, // 4: memos.store.UserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting 4, // 5: memos.store.UserSetting.personal_access_tokens:type_name -> memos.store.PersonalAccessTokensUserSetting - 8, // 6: memos.store.UserSetting.tags:type_name -> memos.store.TagsUserSetting - 9, // 7: memos.store.RefreshTokensUserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting.RefreshToken - 11, // 8: memos.store.PersonalAccessTokensUserSetting.tokens:type_name -> memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken - 12, // 9: memos.store.ShortcutsUserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting.Shortcut - 13, // 10: memos.store.WebhooksUserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting.Webhook - 15, // 11: memos.store.TagMetadata.background_color:type_name -> google.type.Color - 14, // 12: memos.store.TagsUserSetting.tags:type_name -> memos.store.TagsUserSetting.TagsEntry - 16, // 13: memos.store.RefreshTokensUserSetting.RefreshToken.expires_at:type_name -> google.protobuf.Timestamp - 16, // 14: memos.store.RefreshTokensUserSetting.RefreshToken.created_at:type_name -> google.protobuf.Timestamp - 10, // 15: memos.store.RefreshTokensUserSetting.RefreshToken.client_info:type_name -> memos.store.RefreshTokensUserSetting.ClientInfo - 16, // 16: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp - 16, // 17: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp - 16, // 18: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp - 7, // 19: memos.store.TagsUserSetting.TagsEntry.value:type_name -> memos.store.TagMetadata - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 7, // 6: memos.store.RefreshTokensUserSetting.refresh_tokens:type_name -> memos.store.RefreshTokensUserSetting.RefreshToken + 9, // 7: memos.store.PersonalAccessTokensUserSetting.tokens:type_name -> memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken + 10, // 8: memos.store.ShortcutsUserSetting.shortcuts:type_name -> memos.store.ShortcutsUserSetting.Shortcut + 11, // 9: memos.store.WebhooksUserSetting.webhooks:type_name -> memos.store.WebhooksUserSetting.Webhook + 12, // 10: memos.store.RefreshTokensUserSetting.RefreshToken.expires_at:type_name -> google.protobuf.Timestamp + 12, // 11: memos.store.RefreshTokensUserSetting.RefreshToken.created_at:type_name -> google.protobuf.Timestamp + 8, // 12: memos.store.RefreshTokensUserSetting.RefreshToken.client_info:type_name -> memos.store.RefreshTokensUserSetting.ClientInfo + 12, // 13: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.expires_at:type_name -> google.protobuf.Timestamp + 12, // 14: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.created_at:type_name -> google.protobuf.Timestamp + 12, // 15: memos.store.PersonalAccessTokensUserSetting.PersonalAccessToken.last_used_at:type_name -> google.protobuf.Timestamp + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_store_user_setting_proto_init() } @@ -1111,7 +983,6 @@ func file_store_user_setting_proto_init() { (*UserSetting_Webhooks)(nil), (*UserSetting_RefreshTokens)(nil), (*UserSetting_PersonalAccessTokens)(nil), - (*UserSetting_Tags)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1119,7 +990,7 @@ func file_store_user_setting_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_store_user_setting_proto_rawDesc), len(file_store_user_setting_proto_rawDesc)), NumEnums: 1, - NumMessages: 14, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/store/instance_setting.proto b/proto/store/instance_setting.proto index fcfcbdd60..62bb3db44 100644 --- a/proto/store/instance_setting.proto +++ b/proto/store/instance_setting.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package memos.store; +import "google/type/color.proto"; + option go_package = "gen/store"; enum InstanceSettingKey { @@ -14,6 +16,8 @@ enum InstanceSettingKey { STORAGE = 3; // MEMO_RELATED is the key for memo related settings. MEMO_RELATED = 4; + // TAGS is the key for tag metadata. + TAGS = 5; } message InstanceSetting { @@ -23,6 +27,7 @@ message InstanceSetting { InstanceGeneralSetting general_setting = 3; InstanceStorageSetting storage_setting = 4; InstanceMemoRelatedSetting memo_related_setting = 5; + InstanceTagsSetting tags_setting = 6; } } @@ -103,3 +108,12 @@ message InstanceMemoRelatedSetting { // reactions is the list of reactions. repeated string reactions = 7; } + +message InstanceTagMetadata { + // Background color for the tag label. + google.type.Color background_color = 1; +} + +message InstanceTagsSetting { + map tags = 1; +} diff --git a/proto/store/user_setting.proto b/proto/store/user_setting.proto index a485e1a98..6a065e609 100644 --- a/proto/store/user_setting.proto +++ b/proto/store/user_setting.proto @@ -3,7 +3,6 @@ syntax = "proto3"; package memos.store; import "google/protobuf/timestamp.proto"; -import "google/type/color.proto"; option go_package = "gen/store"; @@ -20,8 +19,6 @@ message UserSetting { REFRESH_TOKENS = 6; // Personal access tokens for the user. PERSONAL_ACCESS_TOKENS = 7; - // Tag metadata for the user. - TAGS = 8; } int32 user_id = 1; @@ -33,7 +30,6 @@ message UserSetting { WebhooksUserSetting webhooks = 7; RefreshTokensUserSetting refresh_tokens = 8; PersonalAccessTokensUserSetting personal_access_tokens = 9; - TagsUserSetting tags = 10; } } @@ -115,12 +111,3 @@ message WebhooksUserSetting { } repeated Webhook webhooks = 1; } - -message TagMetadata { - // Background color for the tag label. - google.type.Color background_color = 1; -} - -message TagsUserSetting { - map tags = 1; -} diff --git a/server/router/api/v1/instance_service.go b/server/router/api/v1/instance_service.go index b7661a731..dcee7f301 100644 --- a/server/router/api/v1/instance_service.go +++ b/server/router/api/v1/instance_service.go @@ -3,8 +3,11 @@ package v1 import ( "context" "fmt" + "math" + "strings" "github.com/pkg/errors" + colorpb "google.golang.org/genproto/googleapis/type/color" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -46,6 +49,8 @@ func (s *APIV1Service) GetInstanceSetting(ctx context.Context, request *v1pb.Get _, err = s.Store.GetInstanceMemoRelatedSetting(ctx) case storepb.InstanceSettingKey_STORAGE: _, err = s.Store.GetInstanceStorageSetting(ctx) + case storepb.InstanceSettingKey_TAGS: + _, err = s.Store.GetInstanceTagsSetting(ctx) default: return nil, status.Errorf(codes.InvalidArgument, "unsupported instance setting key: %v", instanceSettingKey) } @@ -95,6 +100,10 @@ func (s *APIV1Service) UpdateInstanceSetting(ctx context.Context, request *v1pb. // TODO: Apply update_mask if specified _ = request.UpdateMask + if err := validateInstanceSetting(request.Setting); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid instance setting: %v", err) + } + updateSetting := convertInstanceSettingToStore(request.Setting) instanceSetting, err := s.Store.UpsertInstanceSetting(ctx, updateSetting) if err != nil { @@ -121,6 +130,10 @@ func convertInstanceSettingFromStore(setting *storepb.InstanceSetting) *v1pb.Ins instanceSetting.Value = &v1pb.InstanceSetting_MemoRelatedSetting_{ MemoRelatedSetting: convertInstanceMemoRelatedSettingFromStore(setting.GetMemoRelatedSetting()), } + case *storepb.InstanceSetting_TagsSetting: + instanceSetting.Value = &v1pb.InstanceSetting_TagsSetting_{ + TagsSetting: convertInstanceTagsSettingFromStore(setting.GetTagsSetting()), + } default: // Leave Value unset for unsupported setting variants. } @@ -148,6 +161,10 @@ func convertInstanceSettingToStore(setting *v1pb.InstanceSetting) *storepb.Insta instanceSetting.Value = &storepb.InstanceSetting_MemoRelatedSetting{ MemoRelatedSetting: convertInstanceMemoRelatedSettingToStore(setting.GetMemoRelatedSetting()), } + case storepb.InstanceSettingKey_TAGS: + instanceSetting.Value = &storepb.InstanceSetting_TagsSetting{ + TagsSetting: convertInstanceTagsSettingToStore(setting.GetTagsSetting()), + } default: // Keep the default GeneralSetting value } @@ -271,6 +288,96 @@ func convertInstanceMemoRelatedSettingToStore(setting *v1pb.InstanceSetting_Memo } } +func convertInstanceTagsSettingFromStore(setting *storepb.InstanceTagsSetting) *v1pb.InstanceSetting_TagsSetting { + if setting == nil { + return nil + } + tags := make(map[string]*v1pb.InstanceSetting_TagMetadata, len(setting.Tags)) + for tag, metadata := range setting.Tags { + tags[tag] = &v1pb.InstanceSetting_TagMetadata{ + BackgroundColor: metadata.GetBackgroundColor(), + } + } + return &v1pb.InstanceSetting_TagsSetting{ + Tags: tags, + } +} + +func convertInstanceTagsSettingToStore(setting *v1pb.InstanceSetting_TagsSetting) *storepb.InstanceTagsSetting { + if setting == nil { + return nil + } + tags := make(map[string]*storepb.InstanceTagMetadata, len(setting.Tags)) + for tag, metadata := range setting.Tags { + tags[tag] = &storepb.InstanceTagMetadata{ + BackgroundColor: metadata.GetBackgroundColor(), + } + } + return &storepb.InstanceTagsSetting{ + Tags: tags, + } +} + +func validateInstanceSetting(setting *v1pb.InstanceSetting) error { + key, err := ExtractInstanceSettingKeyFromName(setting.Name) + if err != nil { + return err + } + if key != storepb.InstanceSettingKey_TAGS.String() { + return nil + } + return validateInstanceTagsSetting(setting.GetTagsSetting()) +} + +func validateInstanceTagsSetting(setting *v1pb.InstanceSetting_TagsSetting) error { + if setting == nil { + return errors.New("tags setting is required") + } + for tag, metadata := range setting.Tags { + if strings.TrimSpace(tag) == "" { + return errors.New("tag key cannot be empty") + } + if metadata == nil { + return errors.Errorf("tag metadata is required for %q", tag) + } + if metadata.GetBackgroundColor() == nil { + return errors.Errorf("background_color is required for %q", tag) + } + if err := validateInstanceColor(metadata.GetBackgroundColor()); err != nil { + return errors.Wrapf(err, "background_color for %q", tag) + } + } + return nil +} + +func validateInstanceColor(color *colorpb.Color) error { + if err := validateInstanceColorComponent("red", color.GetRed()); err != nil { + return err + } + if err := validateInstanceColorComponent("green", color.GetGreen()); err != nil { + return err + } + if err := validateInstanceColorComponent("blue", color.GetBlue()); err != nil { + return err + } + if alpha := color.GetAlpha(); alpha != nil { + if err := validateInstanceColorComponent("alpha", alpha.GetValue()); err != nil { + return err + } + } + return nil +} + +func validateInstanceColorComponent(name string, value float32) error { + if math.IsNaN(float64(value)) || math.IsInf(float64(value), 0) { + return errors.Errorf("%s must be a finite number", name) + } + if value < 0 || value > 1 { + return errors.Errorf("%s must be between 0 and 1", name) + } + return nil +} + func (s *APIV1Service) GetInstanceAdmin(ctx context.Context) (*v1pb.User, error) { adminUserType := store.RoleAdmin user, err := s.Store.GetUser(ctx, &store.FindUser{ diff --git a/server/router/api/v1/test/instance_service_test.go b/server/router/api/v1/test/instance_service_test.go index 2043cf8b6..2fb9ff6e4 100644 --- a/server/router/api/v1/test/instance_service_test.go +++ b/server/router/api/v1/test/instance_service_test.go @@ -5,6 +5,8 @@ import ( "testing" "github.com/stretchr/testify/require" + colorpb "google.golang.org/genproto/googleapis/type/color" + "google.golang.org/protobuf/types/known/fieldmaskpb" v1pb "github.com/usememos/memos/proto/gen/api/v1" ) @@ -186,6 +188,22 @@ func TestGetInstanceSetting(t *testing.T) { require.NotNil(t, memoRelatedSetting) }) + t.Run("GetInstanceSetting - tags setting", func(t *testing.T) { + ts := NewTestService(t) + defer ts.Cleanup() + + req := &v1pb.GetInstanceSettingRequest{ + Name: "instance/settings/TAGS", + } + resp, err := ts.Service.GetInstanceSetting(ctx, req) + + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, "instance/settings/TAGS", resp.Name) + require.NotNil(t, resp.GetTagsSetting()) + require.Empty(t, resp.GetTagsSetting().GetTags()) + }) + t.Run("GetInstanceSetting - invalid setting name", func(t *testing.T) { // Create test service for this specific test ts := NewTestService(t) @@ -202,3 +220,67 @@ func TestGetInstanceSetting(t *testing.T) { require.Contains(t, err.Error(), "invalid instance setting name") }) } + +func TestUpdateInstanceSetting(t *testing.T) { + ctx := context.Background() + + t.Run("UpdateInstanceSetting - tags setting", func(t *testing.T) { + ts := NewTestService(t) + defer ts.Cleanup() + + hostUser, err := ts.CreateHostUser(ctx, "admin") + require.NoError(t, err) + + resp, err := ts.Service.UpdateInstanceSetting(ts.CreateUserContext(ctx, hostUser.ID), &v1pb.UpdateInstanceSettingRequest{ + Setting: &v1pb.InstanceSetting{ + Name: "instance/settings/TAGS", + Value: &v1pb.InstanceSetting_TagsSetting_{ + TagsSetting: &v1pb.InstanceSetting_TagsSetting{ + Tags: map[string]*v1pb.InstanceSetting_TagMetadata{ + "bug": { + BackgroundColor: &colorpb.Color{ + Red: 0.9, + Green: 0.1, + Blue: 0.1, + }, + }, + }, + }, + }, + }, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"tags"}}, + }) + require.NoError(t, err) + require.NotNil(t, resp.GetTagsSetting()) + require.Contains(t, resp.GetTagsSetting().GetTags(), "bug") + }) + + t.Run("UpdateInstanceSetting - invalid tags color", func(t *testing.T) { + ts := NewTestService(t) + defer ts.Cleanup() + + hostUser, err := ts.CreateHostUser(ctx, "admin") + require.NoError(t, err) + + _, err = ts.Service.UpdateInstanceSetting(ts.CreateUserContext(ctx, hostUser.ID), &v1pb.UpdateInstanceSettingRequest{ + Setting: &v1pb.InstanceSetting{ + Name: "instance/settings/TAGS", + Value: &v1pb.InstanceSetting_TagsSetting_{ + TagsSetting: &v1pb.InstanceSetting_TagsSetting{ + Tags: map[string]*v1pb.InstanceSetting_TagMetadata{ + "bug": { + BackgroundColor: &colorpb.Color{ + Red: 1.2, + Green: 0.1, + Blue: 0.1, + }, + }, + }, + }, + }, + }, + }) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid instance setting") + }) +} diff --git a/server/router/api/v1/test/user_setting_test.go b/server/router/api/v1/test/user_setting_test.go deleted file mode 100644 index d6d7ec4f8..000000000 --- a/server/router/api/v1/test/user_setting_test.go +++ /dev/null @@ -1,144 +0,0 @@ -package test - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - colorpb "google.golang.org/genproto/googleapis/type/color" - "google.golang.org/protobuf/types/known/fieldmaskpb" - - apiv1 "github.com/usememos/memos/proto/gen/api/v1" -) - -func TestUserSettingTags(t *testing.T) { - t.Parallel() - ctx := context.Background() - - t.Run("GetUserSetting returns empty tags setting by default", func(t *testing.T) { - ts := NewTestService(t) - defer ts.Cleanup() - - user, err := ts.CreateHostUser(ctx, "tags-default") - require.NoError(t, err) - - response, err := ts.Service.GetUserSetting(ts.CreateUserContext(ctx, user.ID), &apiv1.GetUserSettingRequest{ - Name: fmt.Sprintf("users/%d/settings/TAGS", user.ID), - }) - require.NoError(t, err) - require.NotNil(t, response) - require.NotNil(t, response.GetTagsSetting()) - require.Empty(t, response.GetTagsSetting().GetTags()) - }) - - t.Run("UpdateUserSetting replaces tag metadata", func(t *testing.T) { - ts := NewTestService(t) - defer ts.Cleanup() - - user, err := ts.CreateHostUser(ctx, "tags-update") - require.NoError(t, err) - userCtx := ts.CreateUserContext(ctx, user.ID) - - settingName := fmt.Sprintf("users/%d/settings/TAGS", user.ID) - updateRequest := &apiv1.UpdateUserSettingRequest{ - Setting: &apiv1.UserSetting{ - Name: settingName, - Value: &apiv1.UserSetting_TagsSetting_{ - TagsSetting: &apiv1.UserSetting_TagsSetting{ - Tags: map[string]*apiv1.UserSetting_TagMetadata{ - "bug": { - BackgroundColor: &colorpb.Color{ - Red: 0.9, - Green: 0.1, - Blue: 0.1, - }, - }, - }, - }, - }, - }, - UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"tags"}}, - } - - response, err := ts.Service.UpdateUserSetting(userCtx, updateRequest) - require.NoError(t, err) - require.NotNil(t, response.GetTagsSetting()) - require.Contains(t, response.GetTagsSetting().GetTags(), "bug") - require.InDelta(t, 0.9, response.GetTagsSetting().GetTags()["bug"].GetBackgroundColor().GetRed(), 0.0001) - - getResponse, err := ts.Service.GetUserSetting(userCtx, &apiv1.GetUserSettingRequest{Name: settingName}) - require.NoError(t, err) - require.Len(t, getResponse.GetTagsSetting().GetTags(), 1) - require.Contains(t, getResponse.GetTagsSetting().GetTags(), "bug") - }) - - t.Run("UpdateUserSetting rejects invalid color", func(t *testing.T) { - ts := NewTestService(t) - defer ts.Cleanup() - - user, err := ts.CreateHostUser(ctx, "tags-invalid") - require.NoError(t, err) - - _, err = ts.Service.UpdateUserSetting(ts.CreateUserContext(ctx, user.ID), &apiv1.UpdateUserSettingRequest{ - Setting: &apiv1.UserSetting{ - Name: fmt.Sprintf("users/%d/settings/TAGS", user.ID), - Value: &apiv1.UserSetting_TagsSetting_{ - TagsSetting: &apiv1.UserSetting_TagsSetting{ - Tags: map[string]*apiv1.UserSetting_TagMetadata{ - "bug": { - BackgroundColor: &colorpb.Color{ - Red: 1.2, - Green: 0.1, - Blue: 0.1, - }, - }, - }, - }, - }, - }, - UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"tags"}}, - }) - require.Error(t, err) - require.Contains(t, err.Error(), "invalid tags setting") - }) - - t.Run("Other users cannot read or update tag metadata", func(t *testing.T) { - ts := NewTestService(t) - defer ts.Cleanup() - - user, err := ts.CreateHostUser(ctx, "tags-owner") - require.NoError(t, err) - otherUser, err := ts.CreateHostUser(ctx, "tags-other") - require.NoError(t, err) - - settingName := fmt.Sprintf("users/%d/settings/TAGS", user.ID) - _, err = ts.Service.GetUserSetting(ts.CreateUserContext(ctx, otherUser.ID), &apiv1.GetUserSettingRequest{ - Name: settingName, - }) - require.Error(t, err) - require.Contains(t, err.Error(), "permission denied") - - _, err = ts.Service.UpdateUserSetting(ts.CreateUserContext(ctx, otherUser.ID), &apiv1.UpdateUserSettingRequest{ - Setting: &apiv1.UserSetting{ - Name: settingName, - Value: &apiv1.UserSetting_TagsSetting_{ - TagsSetting: &apiv1.UserSetting_TagsSetting{ - Tags: map[string]*apiv1.UserSetting_TagMetadata{ - "bug": { - BackgroundColor: &colorpb.Color{ - Red: 0.1, - Green: 0.2, - Blue: 0.3, - }, - }, - }, - }, - }, - }, - UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"tags"}}, - }) - require.Error(t, err) - require.Contains(t, err.Error(), "permission denied") - }) -} diff --git a/server/router/api/v1/user_service.go b/server/router/api/v1/user_service.go index caaa98919..98b746a6b 100644 --- a/server/router/api/v1/user_service.go +++ b/server/router/api/v1/user_service.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "encoding/hex" "fmt" - "math" "regexp" "strconv" "strings" @@ -15,7 +14,6 @@ import ( "github.com/google/cel-go/common/ast" "github.com/pkg/errors" "golang.org/x/crypto/bcrypt" - colorpb "google.golang.org/genproto/googleapis/type/color" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -334,12 +332,6 @@ func getDefaultUserGeneralSetting() *v1pb.UserSetting_GeneralSetting { } } -func getDefaultUserTagsSetting() *v1pb.UserSetting_TagsSetting { - return &v1pb.UserSetting_TagsSetting{ - Tags: map[string]*v1pb.UserSetting_TagMetadata{}, - } -} - func (s *APIV1Service) GetUserSetting(ctx context.Context, request *v1pb.GetUserSettingRequest) (*v1pb.UserSetting, error) { // Parse resource name: users/{user}/settings/{setting} userID, settingKey, err := ExtractUserIDAndSettingKeyFromName(request.Name) @@ -450,24 +442,6 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda GeneralSetting: updatedGeneral, }, } - case storepb.UserSetting_TAGS: - if len(request.UpdateMask.Paths) != 1 || request.UpdateMask.Paths[0] != "tags" { - return nil, status.Errorf(codes.InvalidArgument, "tags setting only supports update_mask [\"tags\"]") - } - incomingTags := request.Setting.GetTagsSetting() - if incomingTags == nil { - return nil, status.Errorf(codes.InvalidArgument, "tags setting is required") - } - normalizedTags, err := validateAndNormalizeUserTagsSetting(incomingTags) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "invalid tags setting: %v", err) - } - updatedSetting = &v1pb.UserSetting{ - Name: request.Setting.Name, - Value: &v1pb.UserSetting_TagsSetting_{ - TagsSetting: normalizedTags, - }, - } default: return nil, status.Errorf(codes.InvalidArgument, "setting type %s should not be updated via UpdateUserSetting", storeKey.String()) } @@ -521,14 +495,10 @@ func (s *APIV1Service) ListUserSettings(ctx context.Context, request *v1pb.ListU } hasGeneral := false - hasTags := false for _, setting := range settings { if setting.GetGeneralSetting() != nil { hasGeneral = true } - if setting.GetTagsSetting() != nil { - hasTags = true - } } if !hasGeneral { defaultGeneral := &v1pb.UserSetting{ @@ -539,16 +509,6 @@ func (s *APIV1Service) ListUserSettings(ctx context.Context, request *v1pb.ListU } settings = append([]*v1pb.UserSetting{defaultGeneral}, settings...) } - if !hasTags { - defaultTags := &v1pb.UserSetting{ - Name: fmt.Sprintf("users/%d/settings/%s", userID, convertSettingKeyFromStore(storepb.UserSetting_TAGS)), - Value: &v1pb.UserSetting_TagsSetting_{ - TagsSetting: getDefaultUserTagsSetting(), - }, - } - settings = append(settings, defaultTags) - } - response := &v1pb.ListUserSettingsResponse{ Settings: settings, TotalSize: int32(len(settings)), @@ -1037,8 +997,6 @@ func convertSettingKeyToStore(key string) (storepb.UserSetting_Key, error) { return storepb.UserSetting_GENERAL, nil case v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_WEBHOOKS)]: return storepb.UserSetting_WEBHOOKS, nil - case v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_TAGS)]: - return storepb.UserSetting_TAGS, nil default: return storepb.UserSetting_KEY_UNSPECIFIED, errors.Errorf("unknown setting key: %s", key) } @@ -1053,8 +1011,6 @@ func convertSettingKeyFromStore(key storepb.UserSetting_Key) string { return "SHORTCUTS" // Not defined in API proto case storepb.UserSetting_WEBHOOKS: return v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_WEBHOOKS)] - case storepb.UserSetting_TAGS: - return v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_TAGS)] default: return "unknown" } @@ -1076,10 +1032,6 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32 Webhooks: []*v1pb.UserWebhook{}, }, } - case storepb.UserSetting_TAGS: - setting.Value = &v1pb.UserSetting_TagsSetting_{ - TagsSetting: getDefaultUserTagsSetting(), - } default: // Default to general setting setting.Value = &v1pb.UserSetting_GeneralSetting_{ @@ -1125,19 +1077,6 @@ func convertUserSettingFromStore(storeSetting *storepb.UserSetting, userID int32 Webhooks: apiWebhooks, }, } - case storepb.UserSetting_TAGS: - tags := storeSetting.GetTags() - apiTags := make(map[string]*v1pb.UserSetting_TagMetadata, len(tags.GetTags())) - for tag, metadata := range tags.GetTags() { - apiTags[tag] = &v1pb.UserSetting_TagMetadata{ - BackgroundColor: metadata.GetBackgroundColor(), - } - } - setting.Value = &v1pb.UserSetting_TagsSetting_{ - TagsSetting: &v1pb.UserSetting_TagsSetting{ - Tags: apiTags, - }, - } default: // Default to general setting if unknown key setting.Value = &v1pb.UserSetting_GeneralSetting_{ @@ -1187,22 +1126,6 @@ func convertUserSettingToStore(apiSetting *v1pb.UserSetting, userID int32, key s } else { return nil, errors.Errorf("webhooks setting is required") } - case storepb.UserSetting_TAGS: - if tags := apiSetting.GetTagsSetting(); tags != nil { - storeTags := make(map[string]*storepb.TagMetadata, len(tags.GetTags())) - for tag, metadata := range tags.GetTags() { - storeTags[tag] = &storepb.TagMetadata{ - BackgroundColor: metadata.GetBackgroundColor(), - } - } - storeSetting.Value = &storepb.UserSetting_Tags{ - Tags: &storepb.TagsUserSetting{ - Tags: storeTags, - }, - } - } else { - return nil, errors.Errorf("tags setting is required") - } default: return nil, errors.Errorf("unsupported setting key: %v", key) } @@ -1220,59 +1143,6 @@ func extractWebhookIDFromName(name string) string { return "" } -func validateAndNormalizeUserTagsSetting(tagsSetting *v1pb.UserSetting_TagsSetting) (*v1pb.UserSetting_TagsSetting, error) { - normalized := &v1pb.UserSetting_TagsSetting{ - Tags: make(map[string]*v1pb.UserSetting_TagMetadata, len(tagsSetting.GetTags())), - } - for tag, metadata := range tagsSetting.GetTags() { - if strings.TrimSpace(tag) == "" { - return nil, errors.New("tag key cannot be empty") - } - if metadata == nil { - return nil, errors.Errorf("tag metadata is required for %q", tag) - } - backgroundColor := metadata.GetBackgroundColor() - if backgroundColor == nil { - return nil, errors.Errorf("background_color is required for %q", tag) - } - if err := validateColor(backgroundColor); err != nil { - return nil, errors.Wrapf(err, "background_color for %q", tag) - } - normalized.Tags[tag] = &v1pb.UserSetting_TagMetadata{ - BackgroundColor: backgroundColor, - } - } - return normalized, nil -} - -func validateColor(color *colorpb.Color) error { - if err := validateColorComponent("red", color.GetRed()); err != nil { - return err - } - if err := validateColorComponent("green", color.GetGreen()); err != nil { - return err - } - if err := validateColorComponent("blue", color.GetBlue()); err != nil { - return err - } - if alpha := color.GetAlpha(); alpha != nil { - if err := validateColorComponent("alpha", alpha.GetValue()); err != nil { - return err - } - } - return nil -} - -func validateColorComponent(name string, value float32) error { - if math.IsNaN(float64(value)) || math.IsInf(float64(value), 0) { - return errors.Errorf("%s must be a finite number", name) - } - if value < 0 || value > 1 { - return errors.Errorf("%s must be between 0 and 1", name) - } - return nil -} - // extractUsernameFromFilter extracts username from the filter string using CEL. // Supported filter format: "username == 'steven'" // Returns the username value and an error if the filter format is invalid. diff --git a/store/instance_setting.go b/store/instance_setting.go index 3b44ce1a5..2acc91fa1 100644 --- a/store/instance_setting.go +++ b/store/instance_setting.go @@ -37,6 +37,8 @@ func (s *Store) UpsertInstanceSetting(ctx context.Context, upsert *storepb.Insta valueBytes, err = protojson.Marshal(upsert.GetStorageSetting()) } else if upsert.Key == storepb.InstanceSettingKey_MEMO_RELATED { valueBytes, err = protojson.Marshal(upsert.GetMemoRelatedSetting()) + } else if upsert.Key == storepb.InstanceSettingKey_TAGS { + valueBytes, err = protojson.Marshal(upsert.GetTagsSetting()) } else { return nil, errors.Errorf("unsupported instance setting key: %v", upsert.Key) } @@ -168,6 +170,28 @@ func (s *Store) GetInstanceMemoRelatedSetting(ctx context.Context) (*storepb.Ins return instanceMemoRelatedSetting, nil } +func (s *Store) GetInstanceTagsSetting(ctx context.Context) (*storepb.InstanceTagsSetting, error) { + instanceSetting, err := s.GetInstanceSetting(ctx, &FindInstanceSetting{ + Name: storepb.InstanceSettingKey_TAGS.String(), + }) + if err != nil { + return nil, errors.Wrap(err, "failed to get instance tags setting") + } + + instanceTagsSetting := &storepb.InstanceTagsSetting{} + if instanceSetting != nil { + instanceTagsSetting = instanceSetting.GetTagsSetting() + } + if instanceTagsSetting.Tags == nil { + instanceTagsSetting.Tags = map[string]*storepb.InstanceTagMetadata{} + } + s.instanceSettingCache.Set(ctx, storepb.InstanceSettingKey_TAGS.String(), &storepb.InstanceSetting{ + Key: storepb.InstanceSettingKey_TAGS, + Value: &storepb.InstanceSetting_TagsSetting{TagsSetting: instanceTagsSetting}, + }) + return instanceTagsSetting, nil +} + const ( defaultInstanceStorageType = storepb.InstanceStorageSetting_LOCAL defaultInstanceUploadSizeLimitMb = 30 @@ -231,6 +255,12 @@ func convertInstanceSettingFromRaw(instanceSettingRaw *InstanceSetting) (*storep return nil, err } instanceSetting.Value = &storepb.InstanceSetting_MemoRelatedSetting{MemoRelatedSetting: memoRelatedSetting} + case storepb.InstanceSettingKey_TAGS.String(): + tagsSetting := &storepb.InstanceTagsSetting{} + if err := protojsonUnmarshaler.Unmarshal([]byte(instanceSettingRaw.Value), tagsSetting); err != nil { + return nil, err + } + instanceSetting.Value = &storepb.InstanceSetting_TagsSetting{TagsSetting: tagsSetting} default: // Skip unsupported instance setting key. return nil, nil diff --git a/store/test/instance_setting_test.go b/store/test/instance_setting_test.go index 241c3e26e..7c4c97758 100644 --- a/store/test/instance_setting_test.go +++ b/store/test/instance_setting_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + colorpb "google.golang.org/genproto/googleapis/type/color" storepb "github.com/usememos/memos/proto/gen/store" "github.com/usememos/memos/store" @@ -220,6 +221,42 @@ func TestInstanceSettingStorageSetting(t *testing.T) { ts.Close() } +func TestInstanceSettingTagsSetting(t *testing.T) { + t.Parallel() + ctx := context.Background() + ts := NewTestingStore(ctx, t) + + tagsSetting, err := ts.GetInstanceTagsSetting(ctx) + require.NoError(t, err) + require.NotNil(t, tagsSetting) + require.Empty(t, tagsSetting.Tags) + + _, err = ts.UpsertInstanceSetting(ctx, &storepb.InstanceSetting{ + Key: storepb.InstanceSettingKey_TAGS, + Value: &storepb.InstanceSetting_TagsSetting{ + TagsSetting: &storepb.InstanceTagsSetting{ + Tags: map[string]*storepb.InstanceTagMetadata{ + "bug": { + BackgroundColor: &colorpb.Color{ + Red: 0.9, + Green: 0.1, + Blue: 0.1, + }, + }, + }, + }, + }, + }) + require.NoError(t, err) + + tagsSetting, err = ts.GetInstanceTagsSetting(ctx) + require.NoError(t, err) + require.Contains(t, tagsSetting.Tags, "bug") + require.InDelta(t, 0.9, tagsSetting.Tags["bug"].GetBackgroundColor().GetRed(), 0.0001) + + ts.Close() +} + func TestInstanceSettingListAll(t *testing.T) { t.Parallel() ctx := context.Background() diff --git a/store/test/user_setting_test.go b/store/test/user_setting_test.go index 29d9df559..58f6f247c 100644 --- a/store/test/user_setting_test.go +++ b/store/test/user_setting_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/stretchr/testify/require" - colorpb "google.golang.org/genproto/googleapis/type/color" "google.golang.org/protobuf/types/known/timestamppb" storepb "github.com/usememos/memos/proto/gen/store" @@ -105,48 +104,6 @@ func TestUserSettingUpsertUpdate(t *testing.T) { ts.Close() } -func TestUserSettingTags(t *testing.T) { - t.Parallel() - ctx := context.Background() - ts := NewTestingStore(ctx, t) - user, err := createTestingHostUser(ctx, ts) - require.NoError(t, err) - - _, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{ - UserId: user.ID, - Key: storepb.UserSetting_TAGS, - Value: &storepb.UserSetting_Tags{ - Tags: &storepb.TagsUserSetting{ - Tags: map[string]*storepb.TagMetadata{ - "bug": { - BackgroundColor: &colorpb.Color{ - Red: 0.1, - Green: 0.2, - Blue: 0.3, - }, - }, - }, - }, - }, - }) - require.NoError(t, err) - - setting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{ - UserID: &user.ID, - Key: storepb.UserSetting_TAGS, - }) - require.NoError(t, err) - require.NotNil(t, setting) - require.Contains(t, setting.GetTags().Tags, "bug") - require.InDelta(t, 0.1, setting.GetTags().Tags["bug"].GetBackgroundColor().GetRed(), 0.0001) - - list, err := ts.ListUserSettings(ctx, &store.FindUserSetting{UserID: &user.ID}) - require.NoError(t, err) - require.Len(t, list, 1) - - ts.Close() -} - func TestUserSettingRefreshTokens(t *testing.T) { t.Parallel() ctx := context.Background() diff --git a/store/user_setting.go b/store/user_setting.go index 56e65e9d9..40a1c0480 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -431,12 +431,6 @@ func convertUserSettingFromRaw(raw *UserSetting) (*storepb.UserSetting, error) { return nil, err } userSetting.Value = &storepb.UserSetting_Webhooks{Webhooks: webhooksUserSetting} - case storepb.UserSetting_TAGS: - tagsUserSetting := &storepb.TagsUserSetting{} - if err := protojsonUnmarshaler.Unmarshal([]byte(raw.Value), tagsUserSetting); err != nil { - return nil, err - } - userSetting.Value = &storepb.UserSetting_Tags{Tags: tagsUserSetting} default: return nil, nil } @@ -485,13 +479,6 @@ func convertUserSettingToRaw(userSetting *storepb.UserSetting) (*UserSetting, er return nil, err } raw.Value = string(value) - case storepb.UserSetting_TAGS: - tagsUserSetting := userSetting.GetTags() - value, err := protojson.Marshal(tagsUserSetting) - if err != nil { - return nil, err - } - raw.Value = string(value) default: return nil, errors.Errorf("unsupported user setting key: %v", userSetting.Key) } diff --git a/web/src/types/proto/api/v1/instance_service_pb.ts b/web/src/types/proto/api/v1/instance_service_pb.ts index cee832955..b3311189f 100644 --- a/web/src/types/proto/api/v1/instance_service_pb.ts +++ b/web/src/types/proto/api/v1/instance_service_pb.ts @@ -10,6 +10,8 @@ import { file_google_api_annotations } from "../../google/api/annotations_pb"; import { file_google_api_client } from "../../google/api/client_pb"; import { file_google_api_field_behavior } from "../../google/api/field_behavior_pb"; import { file_google_api_resource } from "../../google/api/resource_pb"; +import type { Color } from "../../google/type/color_pb"; +import { file_google_type_color } from "../../google/type/color_pb"; import type { FieldMask } from "@bufbuild/protobuf/wkt"; import { file_google_protobuf_field_mask } from "@bufbuild/protobuf/wkt"; import type { Message } from "@bufbuild/protobuf"; @@ -18,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/instance_service.proto. */ export const file_api_v1_instance_service: GenFile = /*@__PURE__*/ - fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxImkKD0luc3RhbmNlUHJvZmlsZRIPCgd2ZXJzaW9uGAIgASgJEgwKBGRlbW8YAyABKAgSFAoMaW5zdGFuY2VfdXJsGAYgASgJEiEKBWFkbWluGAcgASgLMhIubWVtb3MuYXBpLnYxLlVzZXIiGwoZR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdCKzCwoPSW5zdGFuY2VTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJHCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRwoPc3RvcmFnZV9zZXR0aW5nGAMgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZ0gAElAKFG1lbW9fcmVsYXRlZF9zZXR0aW5nGAQgASgLMjAubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5NZW1vUmVsYXRlZFNldHRpbmdIABqHAwoOR2VuZXJhbFNldHRpbmcSIgoaZGlzYWxsb3dfdXNlcl9yZWdpc3RyYXRpb24YAiABKAgSHgoWZGlzYWxsb3dfcGFzc3dvcmRfYXV0aBgDIAEoCBIZChFhZGRpdGlvbmFsX3NjcmlwdBgEIAEoCRIYChBhZGRpdGlvbmFsX3N0eWxlGAUgASgJElIKDmN1c3RvbV9wcm9maWxlGAYgASgLMjoubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5HZW5lcmFsU2V0dGluZy5DdXN0b21Qcm9maWxlEh0KFXdlZWtfc3RhcnRfZGF5X29mZnNldBgHIAEoBRIgChhkaXNhbGxvd19jaGFuZ2VfdXNlcm5hbWUYCCABKAgSIAoYZGlzYWxsb3dfY2hhbmdlX25pY2tuYW1lGAkgASgIGkUKDUN1c3RvbVByb2ZpbGUSDQoFdGl0bGUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSEAoIbG9nb191cmwYAyABKAkaugMKDlN0b3JhZ2VTZXR0aW5nEk4KDHN0b3JhZ2VfdHlwZRgBIAEoDjI4Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuU3RvcmFnZVR5cGUSGQoRZmlsZXBhdGhfdGVtcGxhdGUYAiABKAkSHAoUdXBsb2FkX3NpemVfbGltaXRfbWIYAyABKAMSSAoJczNfY29uZmlnGAQgASgLMjUubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZy5TM0NvbmZpZxqGAQoIUzNDb25maWcSFQoNYWNjZXNzX2tleV9pZBgBIAEoCRIZChFhY2Nlc3Nfa2V5X3NlY3JldBgCIAEoCRIQCghlbmRwb2ludBgDIAEoCRIOCgZyZWdpb24YBCABKAkSDgoGYnVja2V0GAUgASgJEhYKDnVzZV9wYXRoX3N0eWxlGAYgASgIIkwKC1N0b3JhZ2VUeXBlEhwKGFNUT1JBR0VfVFlQRV9VTlNQRUNJRklFRBAAEgwKCERBVEFCQVNFEAESCQoFTE9DQUwQAhIGCgJTMxADGq0BChJNZW1vUmVsYXRlZFNldHRpbmcSIgoaZGlzYWxsb3dfcHVibGljX3Zpc2liaWxpdHkYASABKAgSIAoYZGlzcGxheV93aXRoX3VwZGF0ZV90aW1lGAIgASgIEhwKFGNvbnRlbnRfbGVuZ3RoX2xpbWl0GAMgASgFEiAKGGVuYWJsZV9kb3VibGVfY2xpY2tfZWRpdBgEIAEoCBIRCglyZWFjdGlvbnMYByADKAkiRgoDS2V5EhMKD0tFWV9VTlNQRUNJRklFRBAAEgsKB0dFTkVSQUwQARILCgdTVE9SQUdFEAISEAoMTUVNT19SRUxBVEVEEAM6YepBXgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZxIbaW5zdGFuY2Uvc2V0dGluZ3Mve3NldHRpbmd9KhBpbnN0YW5jZVNldHRpbmdzMg9pbnN0YW5jZVNldHRpbmdCBwoFdmFsdWUiTwoZR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIyCgRuYW1lGAEgASgJQiTgQQL6QR4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmciiQEKHFVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMwoHc2V0dGluZxgBIAEoCzIdLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmdCA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBATLbAwoPSW5zdGFuY2VTZXJ2aWNlEn4KEkdldEluc3RhbmNlUHJvZmlsZRInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlUHJvZmlsZSIggtPkkwIaEhgvYXBpL3YxL2luc3RhbmNlL3Byb2ZpbGUSjwEKEkdldEluc3RhbmNlU2V0dGluZxInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfRK1AQoVVXBkYXRlSW5zdGFuY2VTZXR0aW5nEioubWVtb3MuYXBpLnYxLlVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIlHaQRNzZXR0aW5nLHVwZGF0ZV9tYXNrgtPkkwI1OgdzZXR0aW5nMiovYXBpL3YxL3tzZXR0aW5nLm5hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn1CrAEKEGNvbS5tZW1vcy5hcGkudjFCFEluc3RhbmNlU2VydmljZVByb3RvUAFaMGdpdGh1Yi5jb20vdXNlbWVtb3MvbWVtb3MvcHJvdG8vZ2VuL2FwaS92MTthcGl2MaICA01BWKoCDE1lbW9zLkFwaS5WMcoCDE1lbW9zXEFwaVxWMeICGE1lbW9zXEFwaVxWMVxHUEJNZXRhZGF0YeoCDk1lbW9zOjpBcGk6OlYxYgZwcm90bzM", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_field_mask]); + fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxImkKD0luc3RhbmNlUHJvZmlsZRIPCgd2ZXJzaW9uGAIgASgJEgwKBGRlbW8YAyABKAgSFAoMaW5zdGFuY2VfdXJsGAYgASgJEiEKBWFkbWluGAcgASgLMhIubWVtb3MuYXBpLnYxLlVzZXIiGwoZR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdCLoDQoPSW5zdGFuY2VTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJHCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRwoPc3RvcmFnZV9zZXR0aW5nGAMgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZ0gAElAKFG1lbW9fcmVsYXRlZF9zZXR0aW5nGAQgASgLMjAubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5NZW1vUmVsYXRlZFNldHRpbmdIABJBCgx0YWdzX3NldHRpbmcYBSABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ3NTZXR0aW5nSAAahwMKDkdlbmVyYWxTZXR0aW5nEiIKGmRpc2FsbG93X3VzZXJfcmVnaXN0cmF0aW9uGAIgASgIEh4KFmRpc2FsbG93X3Bhc3N3b3JkX2F1dGgYAyABKAgSGQoRYWRkaXRpb25hbF9zY3JpcHQYBCABKAkSGAoQYWRkaXRpb25hbF9zdHlsZRgFIAEoCRJSCg5jdXN0b21fcHJvZmlsZRgGIAEoCzI6Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuR2VuZXJhbFNldHRpbmcuQ3VzdG9tUHJvZmlsZRIdChV3ZWVrX3N0YXJ0X2RheV9vZmZzZXQYByABKAUSIAoYZGlzYWxsb3dfY2hhbmdlX3VzZXJuYW1lGAggASgIEiAKGGRpc2FsbG93X2NoYW5nZV9uaWNrbmFtZRgJIAEoCBpFCg1DdXN0b21Qcm9maWxlEg0KBXRpdGxlGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJEhAKCGxvZ29fdXJsGAMgASgJGroDCg5TdG9yYWdlU2V0dGluZxJOCgxzdG9yYWdlX3R5cGUYASABKA4yOC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nLlN0b3JhZ2VUeXBlEhkKEWZpbGVwYXRoX3RlbXBsYXRlGAIgASgJEhwKFHVwbG9hZF9zaXplX2xpbWl0X21iGAMgASgDEkgKCXMzX2NvbmZpZxgEIAEoCzI1Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuUzNDb25maWcahgEKCFMzQ29uZmlnEhUKDWFjY2Vzc19rZXlfaWQYASABKAkSGQoRYWNjZXNzX2tleV9zZWNyZXQYAiABKAkSEAoIZW5kcG9pbnQYAyABKAkSDgoGcmVnaW9uGAQgASgJEg4KBmJ1Y2tldBgFIAEoCRIWCg51c2VfcGF0aF9zdHlsZRgGIAEoCCJMCgtTdG9yYWdlVHlwZRIcChhTVE9SQUdFX1RZUEVfVU5TUEVDSUZJRUQQABIMCghEQVRBQkFTRRABEgkKBUxPQ0FMEAISBgoCUzMQAxqtAQoSTWVtb1JlbGF0ZWRTZXR0aW5nEiIKGmRpc2FsbG93X3B1YmxpY192aXNpYmlsaXR5GAEgASgIEiAKGGRpc3BsYXlfd2l0aF91cGRhdGVfdGltZRgCIAEoCBIcChRjb250ZW50X2xlbmd0aF9saW1pdBgDIAEoBRIgChhlbmFibGVfZG91YmxlX2NsaWNrX2VkaXQYBCABKAgSEQoJcmVhY3Rpb25zGAcgAygJGjsKC1RhZ01ldGFkYXRhEiwKEGJhY2tncm91bmRfY29sb3IYASABKAsyEi5nb29nbGUudHlwZS5Db2xvchqoAQoLVGFnc1NldHRpbmcSQQoEdGFncxgBIAMoCzIzLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnc1NldHRpbmcuVGFnc0VudHJ5GlYKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSOAoFdmFsdWUYAiABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ01ldGFkYXRhOgI4ASJQCgNLZXkSEwoPS0VZX1VOU1BFQ0lGSUVEEAASCwoHR0VORVJBTBABEgsKB1NUT1JBR0UQAhIQCgxNRU1PX1JFTEFURUQQAxIICgRUQUdTEAQ6YepBXgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZxIbaW5zdGFuY2Uvc2V0dGluZ3Mve3NldHRpbmd9KhBpbnN0YW5jZVNldHRpbmdzMg9pbnN0YW5jZVNldHRpbmdCBwoFdmFsdWUiTwoZR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIyCgRuYW1lGAEgASgJQiTgQQL6QR4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmciiQEKHFVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMwoHc2V0dGluZxgBIAEoCzIdLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmdCA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBATLbAwoPSW5zdGFuY2VTZXJ2aWNlEn4KEkdldEluc3RhbmNlUHJvZmlsZRInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlUHJvZmlsZSIggtPkkwIaEhgvYXBpL3YxL2luc3RhbmNlL3Byb2ZpbGUSjwEKEkdldEluc3RhbmNlU2V0dGluZxInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfRK1AQoVVXBkYXRlSW5zdGFuY2VTZXR0aW5nEioubWVtb3MuYXBpLnYxLlVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIlHaQRNzZXR0aW5nLHVwZGF0ZV9tYXNrgtPkkwI1OgdzZXR0aW5nMiovYXBpL3YxL3tzZXR0aW5nLm5hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn1CrAEKEGNvbS5tZW1vcy5hcGkudjFCFEluc3RhbmNlU2VydmljZVByb3RvUAFaMGdpdGh1Yi5jb20vdXNlbWVtb3MvbWVtb3MvcHJvdG8vZ2VuL2FwaS92MTthcGl2MaICA01BWKoCDE1lbW9zLkFwaS5WMcoCDE1lbW9zXEFwaVxWMeICGE1lbW9zXEFwaVxWMVxHUEJNZXRhZGF0YeoCDk1lbW9zOjpBcGk6OlYxYgZwcm90bzM", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_type_color, file_google_protobuf_field_mask]); /** * Instance profile message containing basic instance information. @@ -113,6 +115,12 @@ export type InstanceSetting = Message<"memos.api.v1.InstanceSetting"> & { */ value: InstanceSetting_MemoRelatedSetting; case: "memoRelatedSetting"; + } | { + /** + * @generated from field: memos.api.v1.InstanceSetting.TagsSetting tags_setting = 5; + */ + value: InstanceSetting_TagsSetting; + case: "tagsSetting"; } | { case: undefined; value?: undefined }; }; @@ -400,6 +408,46 @@ export type InstanceSetting_MemoRelatedSetting = Message<"memos.api.v1.InstanceS export const InstanceSetting_MemoRelatedSettingSchema: GenMessage = /*@__PURE__*/ messageDesc(file_api_v1_instance_service, 2, 2); +/** + * Metadata for a tag. + * + * @generated from message memos.api.v1.InstanceSetting.TagMetadata + */ +export type InstanceSetting_TagMetadata = Message<"memos.api.v1.InstanceSetting.TagMetadata"> & { + /** + * Background color for the tag label. + * + * @generated from field: google.type.Color background_color = 1; + */ + backgroundColor?: Color; +}; + +/** + * Describes the message memos.api.v1.InstanceSetting.TagMetadata. + * Use `create(InstanceSetting_TagMetadataSchema)` to create a new message. + */ +export const InstanceSetting_TagMetadataSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_api_v1_instance_service, 2, 3); + +/** + * Tag metadata configuration. + * + * @generated from message memos.api.v1.InstanceSetting.TagsSetting + */ +export type InstanceSetting_TagsSetting = Message<"memos.api.v1.InstanceSetting.TagsSetting"> & { + /** + * @generated from field: map tags = 1; + */ + tags: { [key: string]: InstanceSetting_TagMetadata }; +}; + +/** + * Describes the message memos.api.v1.InstanceSetting.TagsSetting. + * Use `create(InstanceSetting_TagsSettingSchema)` to create a new message. + */ +export const InstanceSetting_TagsSettingSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_api_v1_instance_service, 2, 4); + /** * Enumeration of instance setting keys. * @@ -431,6 +479,13 @@ export enum InstanceSetting_Key { * @generated from enum value: MEMO_RELATED = 3; */ MEMO_RELATED = 3, + + /** + * TAGS is the key for tag metadata. + * + * @generated from enum value: TAGS = 4; + */ + TAGS = 4, } /** diff --git a/web/src/types/proto/api/v1/user_service_pb.ts b/web/src/types/proto/api/v1/user_service_pb.ts index adb33e33a..4a1bc85f6 100644 --- a/web/src/types/proto/api/v1/user_service_pb.ts +++ b/web/src/types/proto/api/v1/user_service_pb.ts @@ -12,15 +12,13 @@ import { file_google_api_field_behavior } from "../../google/api/field_behavior_ import { file_google_api_resource } from "../../google/api/resource_pb"; import type { EmptySchema, FieldMask, Timestamp } from "@bufbuild/protobuf/wkt"; import { file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; -import type { Color } from "../../google/type/color_pb"; -import { file_google_type_color } from "../../google/type/color_pb"; import type { Message } from "@bufbuild/protobuf"; /** * Describes the file api/v1/user_service.proto. */ export const file_api_v1_user_service: GenFile = /*@__PURE__*/ - fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi1gMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIxCgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIJCgVBRE1JThACEggKBFVTRVIQAzo36kE0ChFtZW1vcy5hcGkudjEvVXNlchIMdXNlcnMve3VzZXJ9GgRuYW1lKgV1c2VyczIEdXNlciJzChBMaXN0VXNlcnNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAiABKAlCA+BBARITCgZmaWx0ZXIYAyABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBCABKAhCA+BBASJjChFMaXN0VXNlcnNSZXNwb25zZRIhCgV1c2VycxgBIAMoCzISLm1lbW9zLmFwaS52MS5Vc2VyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIm0KDkdldFVzZXJSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISMgoJcmVhZF9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EEBIogBChFDcmVhdGVVc2VyUmVxdWVzdBIoCgR1c2VyGAEgASgLMhIubWVtb3MuYXBpLnYxLlVzZXJCBuBBAuBBBBIUCgd1c2VyX2lkGAIgASgJQgPgQQESGgoNdmFsaWRhdGVfb25seRgDIAEoCEID4EEBEhcKCnJlcXVlc3RfaWQYBCABKAlCA+BBASKMAQoRVXBkYXRlVXNlclJlcXVlc3QSJQoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQISGgoNYWxsb3dfbWlzc2luZxgDIAEoCEID4EEBIlAKEURlbGV0ZVVzZXJSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISEgoFZm9yY2UYAiABKAhCA+BBASLYAwoJVXNlclN0YXRzEhEKBG5hbWUYASABKAlCA+BBCBI7ChdtZW1vX2Rpc3BsYXlfdGltZXN0YW1wcxgCIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASPgoPbWVtb190eXBlX3N0YXRzGAMgASgLMiUubWVtb3MuYXBpLnYxLlVzZXJTdGF0cy5NZW1vVHlwZVN0YXRzEjgKCXRhZ19jb3VudBgEIAMoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuVGFnQ291bnRFbnRyeRIUCgxwaW5uZWRfbWVtb3MYBSADKAkSGAoQdG90YWxfbWVtb19jb3VudBgGIAEoBRovCg1UYWdDb3VudEVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEaXwoNTWVtb1R5cGVTdGF0cxISCgpsaW5rX2NvdW50GAEgASgFEhIKCmNvZGVfY291bnQYAiABKAUSEgoKdG9kb19jb3VudBgDIAEoBRISCgp1bmRvX2NvdW50GAQgASgFOj/qQTwKFm1lbW9zLmFwaS52MS9Vc2VyU3RhdHMSDHVzZXJzL3t1c2VyfSoJdXNlclN0YXRzMgl1c2VyU3RhdHMiPgoTR2V0VXNlclN0YXRzUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyIhkKF0xpc3RBbGxVc2VyU3RhdHNSZXF1ZXN0IkIKGExpc3RBbGxVc2VyU3RhdHNSZXNwb25zZRImCgVzdGF0cxgBIAMoCzIXLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMiiQYKC1VzZXJTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJDCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyKC5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcuR2VuZXJhbFNldHRpbmdIABJFChB3ZWJob29rc19zZXR0aW5nGAUgASgLMikubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nLldlYmhvb2tzU2V0dGluZ0gAEj0KDHRhZ3Nfc2V0dGluZxgGIAEoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5UYWdzU2V0dGluZ0gAGlcKDkdlbmVyYWxTZXR0aW5nEhMKBmxvY2FsZRgBIAEoCUID4EEBEhwKD21lbW9fdmlzaWJpbGl0eRgDIAEoCUID4EEBEhIKBXRoZW1lGAQgASgJQgPgQQEaPgoPV2ViaG9va3NTZXR0aW5nEisKCHdlYmhvb2tzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rGjsKC1RhZ01ldGFkYXRhEiwKEGJhY2tncm91bmRfY29sb3IYASABKAsyEi5nb29nbGUudHlwZS5Db2xvchqgAQoLVGFnc1NldHRpbmcSPQoEdGFncxgBIAMoCzIvLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5UYWdzU2V0dGluZy5UYWdzRW50cnkaUgoJVGFnc0VudHJ5EgsKA2tleRgBIAEoCRI0CgV2YWx1ZRgCIAEoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5UYWdNZXRhZGF0YToCOAEiPwoDS2V5EhMKD0tFWV9VTlNQRUNJRklFRBAAEgsKB0dFTkVSQUwQARIMCghXRUJIT09LUxAEEggKBFRBR1MQBTpZ6kFWChhtZW1vcy5hcGkudjEvVXNlclNldHRpbmcSH3VzZXJzL3t1c2VyfS9zZXR0aW5ncy97c2V0dGluZ30qDHVzZXJTZXR0aW5nczILdXNlclNldHRpbmdCBwoFdmFsdWUiRwoVR2V0VXNlclNldHRpbmdSZXF1ZXN0Ei4KBG5hbWUYASABKAlCIOBBAvpBGgoYbWVtb3MuYXBpLnYxL1VzZXJTZXR0aW5nIoEBChhVcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QSLwoHc2V0dGluZxgBIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZ0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECInUKF0xpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEidAoYTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlEisKCHNldHRpbmdzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIvICChNQZXJzb25hbEFjY2Vzc1Rva2VuEhEKBG5hbWUYASABKAlCA+BBCBIYCgtkZXNjcmlwdGlvbhgCIAEoCUID4EEBEjMKCmNyZWF0ZWRfYXQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSMwoKZXhwaXJlc19hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBARI1CgxsYXN0X3VzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQM6jAHqQYgBCiBtZW1vcy5hcGkudjEvUGVyc29uYWxBY2Nlc3NUb2tlbhI5dXNlcnMve3VzZXJ9L3BlcnNvbmFsQWNjZXNzVG9rZW5zL3twZXJzb25hbF9hY2Nlc3NfdG9rZW59KhRwZXJzb25hbEFjY2Vzc1Rva2VuczITcGVyc29uYWxBY2Nlc3NUb2tlbiJ9Ch9MaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEikgEKIExpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1Jlc3BvbnNlEkEKFnBlcnNvbmFsX2FjY2Vzc190b2tlbnMYASADKAsyIS5tZW1vcy5hcGkudjEuUGVyc29uYWxBY2Nlc3NUb2tlbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSKFAQogQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhgKC2Rlc2NyaXB0aW9uGAIgASgJQgPgQQESHAoPZXhwaXJlc19pbl9kYXlzGAMgASgFQgPgQQEidAohQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlc3BvbnNlEkAKFXBlcnNvbmFsX2FjY2Vzc190b2tlbhgBIAEoCzIhLm1lbW9zLmFwaS52MS5QZXJzb25hbEFjY2Vzc1Rva2VuEg0KBXRva2VuGAIgASgJIloKIERlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0EjYKBG5hbWUYASABKAlCKOBBAvpBIgogbWVtb3MuYXBpLnYxL1BlcnNvbmFsQWNjZXNzVG9rZW4iqgEKC1VzZXJXZWJob29rEgwKBG5hbWUYASABKAkSCwoDdXJsGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRI0CgtjcmVhdGVfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIuChdMaXN0VXNlcldlYmhvb2tzUmVxdWVzdBITCgZwYXJlbnQYASABKAlCA+BBAiJHChhMaXN0VXNlcldlYmhvb2tzUmVzcG9uc2USKwoId2ViaG9va3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siYAoYQ3JlYXRlVXNlcldlYmhvb2tSZXF1ZXN0EhMKBnBhcmVudBgBIAEoCUID4EECEi8KB3dlYmhvb2sYAiABKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2tCA+BBAiJ8ChhVcGRhdGVVc2VyV2ViaG9va1JlcXVlc3QSLwoHd2ViaG9vaxgBIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9va0ID4EECEi8KC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayItChhEZWxldGVVc2VyV2ViaG9va1JlcXVlc3QSEQoEbmFtZRgBIAEoCUID4EECIvAEChBVc2VyTm90aWZpY2F0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIpCgZzZW5kZXIYAiABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL1VzZXISOgoGc3RhdHVzGAMgASgOMiUubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24uU3RhdHVzQgPgQQESNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNgoEdHlwZRgFIAEoDjIjLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLlR5cGVCA+BBAxJOCgxtZW1vX2NvbW1lbnQYBiABKAsyMS5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5NZW1vQ29tbWVudFBheWxvYWRCA+BBA0gAGjgKEk1lbW9Db21tZW50UGF5bG9hZBIMCgRtZW1vGAEgASgJEhQKDHJlbGF0ZWRfbWVtbxgCIAEoCSI6CgZTdGF0dXMSFgoSU1RBVFVTX1VOU1BFQ0lGSUVEEAASCgoGVU5SRUFEEAESDAoIQVJDSElWRUQQAiIuCgRUeXBlEhQKEFRZUEVfVU5TUEVDSUZJRUQQABIQCgxNRU1PX0NPTU1FTlQQATpw6kFtCh1tZW1vcy5hcGkudjEvVXNlck5vdGlmaWNhdGlvbhIpdXNlcnMve3VzZXJ9L25vdGlmaWNhdGlvbnMve25vdGlmaWNhdGlvbn0aBG5hbWUqDW5vdGlmaWNhdGlvbnMyDG5vdGlmaWNhdGlvbkIJCgdwYXlsb2FkIo8BChxMaXN0VXNlck5vdGlmaWNhdGlvbnNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQESEwoGZmlsdGVyGAQgASgJQgPgQQEibwodTGlzdFVzZXJOb3RpZmljYXRpb25zUmVzcG9uc2USNQoNbm90aWZpY2F0aW9ucxgBIAMoCzIeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSKQAQodVXBkYXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QSOQoMbm90aWZpY2F0aW9uGAEgASgLMh4ubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb25CA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBAiJUCh1EZWxldGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBIzCgRuYW1lGAEgASgJQiXgQQL6QR8KHW1lbW9zLmFwaS52MS9Vc2VyTm90aWZpY2F0aW9uMoMXCgtVc2VyU2VydmljZRJjCglMaXN0VXNlcnMSHi5tZW1vcy5hcGkudjEuTGlzdFVzZXJzUmVxdWVzdBofLm1lbW9zLmFwaS52MS5MaXN0VXNlcnNSZXNwb25zZSIVgtPkkwIPEg0vYXBpL3YxL3VzZXJzEmIKB0dldFVzZXISHC5tZW1vcy5hcGkudjEuR2V0VXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciIl2kEEbmFtZYLT5JMCGBIWL2FwaS92MS97bmFtZT11c2Vycy8qfRJlCgpDcmVhdGVVc2VyEh8ubWVtb3MuYXBpLnYxLkNyZWF0ZVVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiItpBBHVzZXKC0+STAhU6BHVzZXIiDS9hcGkvdjEvdXNlcnMSfwoKVXBkYXRlVXNlchIfLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIjzaQRB1c2VyLHVwZGF0ZV9tYXNrgtPkkwIjOgR1c2VyMhsvYXBpL3YxL3t1c2VyLm5hbWU9dXNlcnMvKn0SbAoKRGVsZXRlVXNlchIfLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIl2kEEbmFtZYLT5JMCGCoWL2FwaS92MS97bmFtZT11c2Vycy8qfRJ+ChBMaXN0QWxsVXNlclN0YXRzEiUubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXNwb25zZSIbgtPkkwIVEhMvYXBpL3YxL3VzZXJzOnN0YXRzEnoKDEdldFVzZXJTdGF0cxIhLm1lbW9zLmFwaS52MS5HZXRVc2VyU3RhdHNSZXF1ZXN0GhcubWVtb3MuYXBpLnYxLlVzZXJTdGF0cyIu2kEEbmFtZYLT5JMCIRIfL2FwaS92MS97bmFtZT11c2Vycy8qfTpnZXRTdGF0cxKCAQoOR2V0VXNlclNldHRpbmcSIy5tZW1vcy5hcGkudjEuR2V0VXNlclNldHRpbmdSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nIjDaQQRuYW1lgtPkkwIjEiEvYXBpL3YxL3tuYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SqAEKEVVwZGF0ZVVzZXJTZXR0aW5nEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyJQ2kETc2V0dGluZyx1cGRhdGVfbWFza4LT5JMCNDoHc2V0dGluZzIpL2FwaS92MS97c2V0dGluZy5uYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SlQEKEExpc3RVc2VyU2V0dGluZ3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9zZXR0aW5ncxK5AQoYTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zEi0ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1JlcXVlc3QaLi5tZW1vcy5hcGkudjEuTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVzcG9uc2UiPtpBBnBhcmVudILT5JMCLxItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zErYBChlDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0Gi8ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXNwb25zZSI4gtPkkwIyOgEqIi0vYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vcGVyc29uYWxBY2Nlc3NUb2tlbnMSoQEKGURlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW4SLi5tZW1vcy5hcGkudjEuRGVsZXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiPNpBBG5hbWWC0+STAi8qLS9hcGkvdjEve25hbWU9dXNlcnMvKi9wZXJzb25hbEFjY2Vzc1Rva2Vucy8qfRKVAQoQTGlzdFVzZXJXZWJob29rcxIlLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVzcG9uc2UiMtpBBnBhcmVudILT5JMCIxIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEpsBChFDcmVhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siQ9pBDnBhcmVudCx3ZWJob29rgtPkkwIsOgd3ZWJob29rIiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vd2ViaG9va3MSqAEKEVVwZGF0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJXZWJob29rUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayJQ2kETd2ViaG9vayx1cGRhdGVfbWFza4LT5JMCNDoHd2ViaG9vazIpL2FwaS92MS97d2ViaG9vay5uYW1lPXVzZXJzLyovd2ViaG9va3MvKn0ShQEKEURlbGV0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJXZWJob29rUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIw2kEEbmFtZYLT5JMCIyohL2FwaS92MS97bmFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EqkBChVMaXN0VXNlck5vdGlmaWNhdGlvbnMSKi5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBorLm1lbW9zLmFwaS52MS5MaXN0VXNlck5vdGlmaWNhdGlvbnNSZXNwb25zZSI32kEGcGFyZW50gtPkkwIoEiYvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vbm90aWZpY2F0aW9ucxLLAQoWVXBkYXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uImTaQRhub3RpZmljYXRpb24sdXBkYXRlX21hc2uC0+STAkM6DG5vdGlmaWNhdGlvbjIzL2FwaS92MS97bm90aWZpY2F0aW9uLm5hbWU9dXNlcnMvKi9ub3RpZmljYXRpb25zLyp9EpQBChZEZWxldGVVc2VyTm90aWZpY2F0aW9uEisubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjXaQQRuYW1lgtPkkwIoKiYvYXBpL3YxL3tuYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfUKoAQoQY29tLm1lbW9zLmFwaS52MUIQVXNlclNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp, file_google_type_color]); + fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi1gMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIxCgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIJCgVBRE1JThACEggKBFVTRVIQAzo36kE0ChFtZW1vcy5hcGkudjEvVXNlchIMdXNlcnMve3VzZXJ9GgRuYW1lKgV1c2VyczIEdXNlciJzChBMaXN0VXNlcnNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAiABKAlCA+BBARITCgZmaWx0ZXIYAyABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBCABKAhCA+BBASJjChFMaXN0VXNlcnNSZXNwb25zZRIhCgV1c2VycxgBIAMoCzISLm1lbW9zLmFwaS52MS5Vc2VyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIm0KDkdldFVzZXJSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISMgoJcmVhZF9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EEBIogBChFDcmVhdGVVc2VyUmVxdWVzdBIoCgR1c2VyGAEgASgLMhIubWVtb3MuYXBpLnYxLlVzZXJCBuBBAuBBBBIUCgd1c2VyX2lkGAIgASgJQgPgQQESGgoNdmFsaWRhdGVfb25seRgDIAEoCEID4EEBEhcKCnJlcXVlc3RfaWQYBCABKAlCA+BBASKMAQoRVXBkYXRlVXNlclJlcXVlc3QSJQoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQISGgoNYWxsb3dfbWlzc2luZxgDIAEoCEID4EEBIlAKEURlbGV0ZVVzZXJSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISEgoFZm9yY2UYAiABKAhCA+BBASLYAwoJVXNlclN0YXRzEhEKBG5hbWUYASABKAlCA+BBCBI7ChdtZW1vX2Rpc3BsYXlfdGltZXN0YW1wcxgCIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASPgoPbWVtb190eXBlX3N0YXRzGAMgASgLMiUubWVtb3MuYXBpLnYxLlVzZXJTdGF0cy5NZW1vVHlwZVN0YXRzEjgKCXRhZ19jb3VudBgEIAMoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuVGFnQ291bnRFbnRyeRIUCgxwaW5uZWRfbWVtb3MYBSADKAkSGAoQdG90YWxfbWVtb19jb3VudBgGIAEoBRovCg1UYWdDb3VudEVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEaXwoNTWVtb1R5cGVTdGF0cxISCgpsaW5rX2NvdW50GAEgASgFEhIKCmNvZGVfY291bnQYAiABKAUSEgoKdG9kb19jb3VudBgDIAEoBRISCgp1bmRvX2NvdW50GAQgASgFOj/qQTwKFm1lbW9zLmFwaS52MS9Vc2VyU3RhdHMSDHVzZXJzL3t1c2VyfSoJdXNlclN0YXRzMgl1c2VyU3RhdHMiPgoTR2V0VXNlclN0YXRzUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyIhkKF0xpc3RBbGxVc2VyU3RhdHNSZXF1ZXN0IkIKGExpc3RBbGxVc2VyU3RhdHNSZXNwb25zZRImCgVzdGF0cxgBIAMoCzIXLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMi4AMKC1VzZXJTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJDCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyKC5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcuR2VuZXJhbFNldHRpbmdIABJFChB3ZWJob29rc19zZXR0aW5nGAUgASgLMikubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nLldlYmhvb2tzU2V0dGluZ0gAGlcKDkdlbmVyYWxTZXR0aW5nEhMKBmxvY2FsZRgBIAEoCUID4EEBEhwKD21lbW9fdmlzaWJpbGl0eRgDIAEoCUID4EEBEhIKBXRoZW1lGAQgASgJQgPgQQEaPgoPV2ViaG9va3NTZXR0aW5nEisKCHdlYmhvb2tzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rIjUKA0tleRITCg9LRVlfVU5TUEVDSUZJRUQQABILCgdHRU5FUkFMEAESDAoIV0VCSE9PS1MQBDpZ6kFWChhtZW1vcy5hcGkudjEvVXNlclNldHRpbmcSH3VzZXJzL3t1c2VyfS9zZXR0aW5ncy97c2V0dGluZ30qDHVzZXJTZXR0aW5nczILdXNlclNldHRpbmdCBwoFdmFsdWUiRwoVR2V0VXNlclNldHRpbmdSZXF1ZXN0Ei4KBG5hbWUYASABKAlCIOBBAvpBGgoYbWVtb3MuYXBpLnYxL1VzZXJTZXR0aW5nIoEBChhVcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QSLwoHc2V0dGluZxgBIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZ0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECInUKF0xpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEidAoYTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlEisKCHNldHRpbmdzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIvICChNQZXJzb25hbEFjY2Vzc1Rva2VuEhEKBG5hbWUYASABKAlCA+BBCBIYCgtkZXNjcmlwdGlvbhgCIAEoCUID4EEBEjMKCmNyZWF0ZWRfYXQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSMwoKZXhwaXJlc19hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBARI1CgxsYXN0X3VzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQM6jAHqQYgBCiBtZW1vcy5hcGkudjEvUGVyc29uYWxBY2Nlc3NUb2tlbhI5dXNlcnMve3VzZXJ9L3BlcnNvbmFsQWNjZXNzVG9rZW5zL3twZXJzb25hbF9hY2Nlc3NfdG9rZW59KhRwZXJzb25hbEFjY2Vzc1Rva2VuczITcGVyc29uYWxBY2Nlc3NUb2tlbiJ9Ch9MaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEikgEKIExpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1Jlc3BvbnNlEkEKFnBlcnNvbmFsX2FjY2Vzc190b2tlbnMYASADKAsyIS5tZW1vcy5hcGkudjEuUGVyc29uYWxBY2Nlc3NUb2tlbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSKFAQogQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhgKC2Rlc2NyaXB0aW9uGAIgASgJQgPgQQESHAoPZXhwaXJlc19pbl9kYXlzGAMgASgFQgPgQQEidAohQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlc3BvbnNlEkAKFXBlcnNvbmFsX2FjY2Vzc190b2tlbhgBIAEoCzIhLm1lbW9zLmFwaS52MS5QZXJzb25hbEFjY2Vzc1Rva2VuEg0KBXRva2VuGAIgASgJIloKIERlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0EjYKBG5hbWUYASABKAlCKOBBAvpBIgogbWVtb3MuYXBpLnYxL1BlcnNvbmFsQWNjZXNzVG9rZW4iqgEKC1VzZXJXZWJob29rEgwKBG5hbWUYASABKAkSCwoDdXJsGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRI0CgtjcmVhdGVfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIuChdMaXN0VXNlcldlYmhvb2tzUmVxdWVzdBITCgZwYXJlbnQYASABKAlCA+BBAiJHChhMaXN0VXNlcldlYmhvb2tzUmVzcG9uc2USKwoId2ViaG9va3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siYAoYQ3JlYXRlVXNlcldlYmhvb2tSZXF1ZXN0EhMKBnBhcmVudBgBIAEoCUID4EECEi8KB3dlYmhvb2sYAiABKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2tCA+BBAiJ8ChhVcGRhdGVVc2VyV2ViaG9va1JlcXVlc3QSLwoHd2ViaG9vaxgBIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9va0ID4EECEi8KC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayItChhEZWxldGVVc2VyV2ViaG9va1JlcXVlc3QSEQoEbmFtZRgBIAEoCUID4EECIvAEChBVc2VyTm90aWZpY2F0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIpCgZzZW5kZXIYAiABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL1VzZXISOgoGc3RhdHVzGAMgASgOMiUubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24uU3RhdHVzQgPgQQESNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNgoEdHlwZRgFIAEoDjIjLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLlR5cGVCA+BBAxJOCgxtZW1vX2NvbW1lbnQYBiABKAsyMS5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5NZW1vQ29tbWVudFBheWxvYWRCA+BBA0gAGjgKEk1lbW9Db21tZW50UGF5bG9hZBIMCgRtZW1vGAEgASgJEhQKDHJlbGF0ZWRfbWVtbxgCIAEoCSI6CgZTdGF0dXMSFgoSU1RBVFVTX1VOU1BFQ0lGSUVEEAASCgoGVU5SRUFEEAESDAoIQVJDSElWRUQQAiIuCgRUeXBlEhQKEFRZUEVfVU5TUEVDSUZJRUQQABIQCgxNRU1PX0NPTU1FTlQQATpw6kFtCh1tZW1vcy5hcGkudjEvVXNlck5vdGlmaWNhdGlvbhIpdXNlcnMve3VzZXJ9L25vdGlmaWNhdGlvbnMve25vdGlmaWNhdGlvbn0aBG5hbWUqDW5vdGlmaWNhdGlvbnMyDG5vdGlmaWNhdGlvbkIJCgdwYXlsb2FkIo8BChxMaXN0VXNlck5vdGlmaWNhdGlvbnNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQESEwoGZmlsdGVyGAQgASgJQgPgQQEibwodTGlzdFVzZXJOb3RpZmljYXRpb25zUmVzcG9uc2USNQoNbm90aWZpY2F0aW9ucxgBIAMoCzIeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSKQAQodVXBkYXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QSOQoMbm90aWZpY2F0aW9uGAEgASgLMh4ubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb25CA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBAiJUCh1EZWxldGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBIzCgRuYW1lGAEgASgJQiXgQQL6QR8KHW1lbW9zLmFwaS52MS9Vc2VyTm90aWZpY2F0aW9uMoMXCgtVc2VyU2VydmljZRJjCglMaXN0VXNlcnMSHi5tZW1vcy5hcGkudjEuTGlzdFVzZXJzUmVxdWVzdBofLm1lbW9zLmFwaS52MS5MaXN0VXNlcnNSZXNwb25zZSIVgtPkkwIPEg0vYXBpL3YxL3VzZXJzEmIKB0dldFVzZXISHC5tZW1vcy5hcGkudjEuR2V0VXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciIl2kEEbmFtZYLT5JMCGBIWL2FwaS92MS97bmFtZT11c2Vycy8qfRJlCgpDcmVhdGVVc2VyEh8ubWVtb3MuYXBpLnYxLkNyZWF0ZVVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiItpBBHVzZXKC0+STAhU6BHVzZXIiDS9hcGkvdjEvdXNlcnMSfwoKVXBkYXRlVXNlchIfLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIjzaQRB1c2VyLHVwZGF0ZV9tYXNrgtPkkwIjOgR1c2VyMhsvYXBpL3YxL3t1c2VyLm5hbWU9dXNlcnMvKn0SbAoKRGVsZXRlVXNlchIfLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIl2kEEbmFtZYLT5JMCGCoWL2FwaS92MS97bmFtZT11c2Vycy8qfRJ+ChBMaXN0QWxsVXNlclN0YXRzEiUubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXNwb25zZSIbgtPkkwIVEhMvYXBpL3YxL3VzZXJzOnN0YXRzEnoKDEdldFVzZXJTdGF0cxIhLm1lbW9zLmFwaS52MS5HZXRVc2VyU3RhdHNSZXF1ZXN0GhcubWVtb3MuYXBpLnYxLlVzZXJTdGF0cyIu2kEEbmFtZYLT5JMCIRIfL2FwaS92MS97bmFtZT11c2Vycy8qfTpnZXRTdGF0cxKCAQoOR2V0VXNlclNldHRpbmcSIy5tZW1vcy5hcGkudjEuR2V0VXNlclNldHRpbmdSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nIjDaQQRuYW1lgtPkkwIjEiEvYXBpL3YxL3tuYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SqAEKEVVwZGF0ZVVzZXJTZXR0aW5nEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyJQ2kETc2V0dGluZyx1cGRhdGVfbWFza4LT5JMCNDoHc2V0dGluZzIpL2FwaS92MS97c2V0dGluZy5uYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SlQEKEExpc3RVc2VyU2V0dGluZ3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9zZXR0aW5ncxK5AQoYTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zEi0ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1JlcXVlc3QaLi5tZW1vcy5hcGkudjEuTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVzcG9uc2UiPtpBBnBhcmVudILT5JMCLxItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zErYBChlDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0Gi8ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXNwb25zZSI4gtPkkwIyOgEqIi0vYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vcGVyc29uYWxBY2Nlc3NUb2tlbnMSoQEKGURlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW4SLi5tZW1vcy5hcGkudjEuRGVsZXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiPNpBBG5hbWWC0+STAi8qLS9hcGkvdjEve25hbWU9dXNlcnMvKi9wZXJzb25hbEFjY2Vzc1Rva2Vucy8qfRKVAQoQTGlzdFVzZXJXZWJob29rcxIlLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVzcG9uc2UiMtpBBnBhcmVudILT5JMCIxIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEpsBChFDcmVhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siQ9pBDnBhcmVudCx3ZWJob29rgtPkkwIsOgd3ZWJob29rIiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vd2ViaG9va3MSqAEKEVVwZGF0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJXZWJob29rUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayJQ2kETd2ViaG9vayx1cGRhdGVfbWFza4LT5JMCNDoHd2ViaG9vazIpL2FwaS92MS97d2ViaG9vay5uYW1lPXVzZXJzLyovd2ViaG9va3MvKn0ShQEKEURlbGV0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJXZWJob29rUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIw2kEEbmFtZYLT5JMCIyohL2FwaS92MS97bmFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EqkBChVMaXN0VXNlck5vdGlmaWNhdGlvbnMSKi5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBorLm1lbW9zLmFwaS52MS5MaXN0VXNlck5vdGlmaWNhdGlvbnNSZXNwb25zZSI32kEGcGFyZW50gtPkkwIoEiYvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vbm90aWZpY2F0aW9ucxLLAQoWVXBkYXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uImTaQRhub3RpZmljYXRpb24sdXBkYXRlX21hc2uC0+STAkM6DG5vdGlmaWNhdGlvbjIzL2FwaS92MS97bm90aWZpY2F0aW9uLm5hbWU9dXNlcnMvKi9ub3RpZmljYXRpb25zLyp9EpQBChZEZWxldGVVc2VyTm90aWZpY2F0aW9uEisubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjXaQQRuYW1lgtPkkwIoKiYvYXBpL3YxL3tuYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfUKoAQoQY29tLm1lbW9zLmFwaS52MUIQVXNlclNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); /** * @generated from message memos.api.v1.User @@ -534,12 +532,6 @@ export type UserSetting = Message<"memos.api.v1.UserSetting"> & { */ value: UserSetting_WebhooksSetting; case: "webhooksSetting"; - } | { - /** - * @generated from field: memos.api.v1.UserSetting.TagsSetting tags_setting = 6; - */ - value: UserSetting_TagsSetting; - case: "tagsSetting"; } | { case: undefined; value?: undefined }; }; @@ -608,46 +600,6 @@ export type UserSetting_WebhooksSetting = Message<"memos.api.v1.UserSetting.Webh export const UserSetting_WebhooksSettingSchema: GenMessage = /*@__PURE__*/ messageDesc(file_api_v1_user_service, 11, 1); -/** - * Metadata for a tag. - * - * @generated from message memos.api.v1.UserSetting.TagMetadata - */ -export type UserSetting_TagMetadata = Message<"memos.api.v1.UserSetting.TagMetadata"> & { - /** - * Background color for the tag label. - * - * @generated from field: google.type.Color background_color = 1; - */ - backgroundColor?: Color; -}; - -/** - * Describes the message memos.api.v1.UserSetting.TagMetadata. - * Use `create(UserSetting_TagMetadataSchema)` to create a new message. - */ -export const UserSetting_TagMetadataSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 11, 2); - -/** - * User tag metadata configuration. - * - * @generated from message memos.api.v1.UserSetting.TagsSetting - */ -export type UserSetting_TagsSetting = Message<"memos.api.v1.UserSetting.TagsSetting"> & { - /** - * @generated from field: map tags = 1; - */ - tags: { [key: string]: UserSetting_TagMetadata }; -}; - -/** - * Describes the message memos.api.v1.UserSetting.TagsSetting. - * Use `create(UserSetting_TagsSettingSchema)` to create a new message. - */ -export const UserSetting_TagsSettingSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_api_v1_user_service, 11, 3); - /** * Enumeration of user setting keys. * @@ -672,13 +624,6 @@ export enum UserSetting_Key { * @generated from enum value: WEBHOOKS = 4; */ WEBHOOKS = 4, - - /** - * TAGS is the key for user tag metadata. - * - * @generated from enum value: TAGS = 5; - */ - TAGS = 5, } /**