chore: tweak link styles

This commit is contained in:
Steven 2024-03-16 23:35:36 +08:00
parent 9c1e2f8137
commit 335a0312f2
7 changed files with 222 additions and 257 deletions

View file

@ -8,20 +8,20 @@ option go_package = "gen/api/v2";
service LinkService {
rpc GetLinkMetadata(GetLinkMetadataRequest) returns (GetLinkMetadataResponse) {
option (google.api.http) = {get: "/api/v2/metadata"};
option (google.api.http) = {get: "/api/v2/link_metadata"};
}
}
message LinkMetadata {
string title = 1;
string description = 2;
string image = 3;
}
message GetLinkMetadataRequest {
string link = 1;
}
message GetLinkMetadataResponse {
LinkMetadata metadata = 1;
LinkMetadata link_metadata = 1;
}
message LinkMetadata {
string title = 1;
string description = 2;
string image = 3;
}

View file

@ -1135,7 +1135,7 @@ Used internally for obfuscating the page token.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| metadata | [LinkMetadata](#memos-api-v2-LinkMetadata) | | |
| link_metadata | [LinkMetadata](#memos-api-v2-LinkMetadata) | | |

View file

@ -21,6 +21,100 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetLinkMetadataRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"`
}
func (x *GetLinkMetadataRequest) Reset() {
*x = GetLinkMetadataRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_link_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetLinkMetadataRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetLinkMetadataRequest) ProtoMessage() {}
func (x *GetLinkMetadataRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_link_service_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetLinkMetadataRequest.ProtoReflect.Descriptor instead.
func (*GetLinkMetadataRequest) Descriptor() ([]byte, []int) {
return file_api_v2_link_service_proto_rawDescGZIP(), []int{0}
}
func (x *GetLinkMetadataRequest) GetLink() string {
if x != nil {
return x.Link
}
return ""
}
type GetLinkMetadataResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
LinkMetadata *LinkMetadata `protobuf:"bytes,1,opt,name=link_metadata,json=linkMetadata,proto3" json:"link_metadata,omitempty"`
}
func (x *GetLinkMetadataResponse) Reset() {
*x = GetLinkMetadataResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_link_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetLinkMetadataResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetLinkMetadataResponse) ProtoMessage() {}
func (x *GetLinkMetadataResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_link_service_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetLinkMetadataResponse.ProtoReflect.Descriptor instead.
func (*GetLinkMetadataResponse) Descriptor() ([]byte, []int) {
return file_api_v2_link_service_proto_rawDescGZIP(), []int{1}
}
func (x *GetLinkMetadataResponse) GetLinkMetadata() *LinkMetadata {
if x != nil {
return x.LinkMetadata
}
return nil
}
type LinkMetadata struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -34,7 +128,7 @@ type LinkMetadata struct {
func (x *LinkMetadata) Reset() {
*x = LinkMetadata{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_link_service_proto_msgTypes[0]
mi := &file_api_v2_link_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -47,7 +141,7 @@ func (x *LinkMetadata) String() string {
func (*LinkMetadata) ProtoMessage() {}
func (x *LinkMetadata) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_link_service_proto_msgTypes[0]
mi := &file_api_v2_link_service_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -60,7 +154,7 @@ func (x *LinkMetadata) ProtoReflect() protoreflect.Message {
// Deprecated: Use LinkMetadata.ProtoReflect.Descriptor instead.
func (*LinkMetadata) Descriptor() ([]byte, []int) {
return file_api_v2_link_service_proto_rawDescGZIP(), []int{0}
return file_api_v2_link_service_proto_rawDescGZIP(), []int{2}
}
func (x *LinkMetadata) GetTitle() string {
@ -84,100 +178,6 @@ func (x *LinkMetadata) GetImage() string {
return ""
}
type GetLinkMetadataRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"`
}
func (x *GetLinkMetadataRequest) Reset() {
*x = GetLinkMetadataRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_link_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetLinkMetadataRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetLinkMetadataRequest) ProtoMessage() {}
func (x *GetLinkMetadataRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_link_service_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetLinkMetadataRequest.ProtoReflect.Descriptor instead.
func (*GetLinkMetadataRequest) Descriptor() ([]byte, []int) {
return file_api_v2_link_service_proto_rawDescGZIP(), []int{1}
}
func (x *GetLinkMetadataRequest) GetLink() string {
if x != nil {
return x.Link
}
return ""
}
type GetLinkMetadataResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Metadata *LinkMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
}
func (x *GetLinkMetadataResponse) Reset() {
*x = GetLinkMetadataResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_link_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetLinkMetadataResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetLinkMetadataResponse) ProtoMessage() {}
func (x *GetLinkMetadataResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_link_service_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetLinkMetadataResponse.ProtoReflect.Descriptor instead.
func (*GetLinkMetadataResponse) Descriptor() ([]byte, []int) {
return file_api_v2_link_service_proto_rawDescGZIP(), []int{2}
}
func (x *GetLinkMetadataResponse) GetMetadata() *LinkMetadata {
if x != nil {
return x.Metadata
}
return nil
}
var File_api_v2_link_service_proto protoreflect.FileDescriptor
var file_api_v2_link_service_proto_rawDesc = []byte{
@ -185,41 +185,42 @@ var file_api_v2_link_service_proto_rawDesc = []byte{
0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a,
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c,
0x69, 0x6e, 0x6b, 0x22, 0x51, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36,
0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0x87, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e,
0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47,
0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d,
0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41,
0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32,
0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2,
0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d,
0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4c, 0x69,
0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x5a, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x3f, 0x0a, 0x0d, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64,
0x61, 0x74, 0x61, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x22, 0x5c, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61,
0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x32,
0x8c, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x7d, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x12, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
0x2f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0xa8,
0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x32, 0x42, 0x10, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa,
0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02,
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18,
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
@ -236,14 +237,14 @@ func file_api_v2_link_service_proto_rawDescGZIP() []byte {
var file_api_v2_link_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_api_v2_link_service_proto_goTypes = []interface{}{
(*LinkMetadata)(nil), // 0: memos.api.v2.LinkMetadata
(*GetLinkMetadataRequest)(nil), // 1: memos.api.v2.GetLinkMetadataRequest
(*GetLinkMetadataResponse)(nil), // 2: memos.api.v2.GetLinkMetadataResponse
(*GetLinkMetadataRequest)(nil), // 0: memos.api.v2.GetLinkMetadataRequest
(*GetLinkMetadataResponse)(nil), // 1: memos.api.v2.GetLinkMetadataResponse
(*LinkMetadata)(nil), // 2: memos.api.v2.LinkMetadata
}
var file_api_v2_link_service_proto_depIdxs = []int32{
0, // 0: memos.api.v2.GetLinkMetadataResponse.metadata:type_name -> memos.api.v2.LinkMetadata
1, // 1: memos.api.v2.LinkService.GetLinkMetadata:input_type -> memos.api.v2.GetLinkMetadataRequest
2, // 2: memos.api.v2.LinkService.GetLinkMetadata:output_type -> memos.api.v2.GetLinkMetadataResponse
2, // 0: memos.api.v2.GetLinkMetadataResponse.link_metadata:type_name -> memos.api.v2.LinkMetadata
0, // 1: memos.api.v2.LinkService.GetLinkMetadata:input_type -> memos.api.v2.GetLinkMetadataRequest
1, // 2: memos.api.v2.LinkService.GetLinkMetadata:output_type -> memos.api.v2.GetLinkMetadataResponse
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
@ -258,18 +259,6 @@ func file_api_v2_link_service_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_api_v2_link_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinkMetadata); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_v2_link_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetLinkMetadataRequest); i {
case 0:
return &v.state
@ -281,7 +270,7 @@ func file_api_v2_link_service_proto_init() {
return nil
}
}
file_api_v2_link_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
file_api_v2_link_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetLinkMetadataResponse); i {
case 0:
return &v.state
@ -293,6 +282,18 @@ func file_api_v2_link_service_proto_init() {
return nil
}
}
file_api_v2_link_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinkMetadata); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{

View file

@ -81,7 +81,7 @@ func RegisterLinkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/metadata"))
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/link_metadata"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -145,7 +145,7 @@ func RegisterLinkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/metadata"))
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/link_metadata"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -165,7 +165,7 @@ func RegisterLinkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
}
var (
pattern_LinkService_GetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "metadata"}, ""))
pattern_LinkService_GetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "link_metadata"}, ""))
)
var (

View file

@ -151,6 +151,25 @@ paths:
type: string
tags:
- InboxService
/api/v2/link_metadata:
get:
operationId: LinkService_GetLinkMetadata
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v2GetLinkMetadataResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: link
in: query
required: false
type: string
tags:
- LinkService
/api/v2/memos:
get:
summary: ListMemos lists memos with pagination and filter.
@ -650,25 +669,6 @@ paths:
type: string
tags:
- MemoService
/api/v2/metadata:
get:
operationId: LinkService_GetLinkMetadata
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v2GetLinkMetadataResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: link
in: query
required: false
type: string
tags:
- LinkService
/api/v2/resources:
get:
summary: ListResources lists all resources.
@ -1813,7 +1813,7 @@ definitions:
v2GetLinkMetadataResponse:
type: object
properties:
metadata:
linkMetadata:
$ref: '#/definitions/v2LinkMetadata'
v2GetMemoByNameResponse:
type: object

View file

@ -14,7 +14,7 @@ func (*APIV2Service) GetLinkMetadata(_ context.Context, request *apiv2pb.GetLink
}
return &apiv2pb.GetLinkMetadataResponse{
Metadata: &apiv2pb.LinkMetadata{
LinkMetadata: &apiv2pb.LinkMetadata{
Title: htmlMeta.Title,
Description: htmlMeta.Description,
Image: htmlMeta.Image,

View file

@ -1,8 +1,6 @@
import { Tooltip, Card, AspectRatio, Box } from "@mui/joy";
import { Link as MLink } from "@mui/joy";
import { Link as MLink, Tooltip } from "@mui/joy";
import { useEffect, useState } from "react";
import { linkServiceClient } from "@/grpcweb";
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
import { LinkMetadata } from "@/types/proto/api/v2/link_service";
interface Props {
@ -10,83 +8,49 @@ interface Props {
text?: string;
}
const getFaviconWithGoogleS2 = (url: string) => {
try {
const urlObject = new URL(url);
return `https://www.google.com/s2/favicons?sz=128&domain=${urlObject.hostname}`;
} catch (error) {
return undefined;
}
};
const Link: React.FC<Props> = ({ text, url }: Props) => {
const [linkMetadata, setLinkMetadata] = useState<LinkMetadata | undefined>();
const { md } = useResponsiveWidth();
const fetchUrlMetadata = async () => {
try {
const response = await linkServiceClient.getLinkMetadata({ link: url }, {});
setLinkMetadata(response.metadata);
} catch (error) {
console.error("Error fetching URL metadata:", error);
return null;
}
};
useEffect(() => {
fetchUrlMetadata();
(async () => {
try {
const { linkMetadata } = await linkServiceClient.getLinkMetadata({ link: url }, {});
setLinkMetadata(linkMetadata);
} catch (error) {
console.error("Error fetching URL metadata:", error);
}
})();
}, [url]);
return (
<>
{md ? (
<div>
<Tooltip
placement="top-end"
variant="solid"
sx={{}}
title={
<Box
sx={{
display: "flex",
flexDirection: "row",
maxWidth: 450,
maxHeight: 300,
}}
>
{linkMetadata?.image ? (
<a href={url} target="_blank" rel="noopener noreferrer" className="flex w-full">
<Card variant="outlined" orientation="vertical" sx={{ width: "100%" }}>
<AspectRatio ratio={"21/9"} objectFit="cover" variant="plain">
<img src={linkMetadata?.image} alt={linkMetadata?.title} className="pointer-events-none" />
</AspectRatio>
<div className="flex-1 overflow-auto w-full">
<div className="flex flex-col justify-between ">
<div>
<h3 className="text-2xl font-semibold tracking-tight truncate">{linkMetadata?.title}</h3>
{linkMetadata?.description && <p className="text-sm truncate">{linkMetadata?.description}</p>}
</div>
</div>
</div>
</Card>
</a>
) : (
<Card variant="soft" orientation="vertical" sx={{ width: "100%" }}>
<div className="flex-1 overflow-auto w-full">
<div className="flex flex-col justify-between ">
<div>
<h3 className="text-2xl font-semibold tracking-tight">{linkMetadata?.title}</h3>
<p className="text-sm text-black/50 dark:text-white/50">No Preview</p>
</div>
</div>
</div>
</Card>
)}
</Box>
}
>
<MLink href={url} underline="none" sx={{ fontWeight: "lg" }}>
{url || text}
</MLink>
</Tooltip>
return linkMetadata ? (
<Tooltip
variant="outlined"
title={
<div className="w-full max-w-64 sm:max-w-96 p-1 flex flex-col">
<a href={url} target="_blank" rel="noopener noreferrer" className="group w-full flex flex-row justify-start items-center gap-1">
<img className="w-5 h-5 pointer-events-none" src={getFaviconWithGoogleS2(url)} alt={linkMetadata?.title} />
<h3 className="text-base truncate dark:opacity-90 group-hover:opacity-80">{linkMetadata?.title}</h3>
</a>
{linkMetadata.description && (
<p className="mt-1 w-full text-sm leading-snug opacity-80 line-clamp-2">{linkMetadata.description}</p>
)}
</div>
) : (
<MLink href={url} underline="none" sx={{ fontWeight: "lg" }}>
{url || text}
</MLink>
)}
</>
}
arrow
>
<MLink href={url}>{url || text}</MLink>
</Tooltip>
) : (
<MLink href={url}>{url || text}</MLink>
);
};