Commit 335a0312 authored by Steven's avatar Steven

chore: tweak link styles

parent 9c1e2f81
......@@ -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;
}
......@@ -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) | | |
......
This diff is collapsed.
......@@ -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 (
......
......@@ -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
......
......@@ -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,
......
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>
);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment