feat(web): use favicon provider

This commit is contained in:
Steven
2024-04-07 20:28:21 +08:00
parent 8649e562dc
commit 5264dc9d8a
6 changed files with 53 additions and 55 deletions

View File

@ -0,0 +1,36 @@
import { useState } from "react";
import { useWorkspaceStore } from "@/stores";
import Icon from "./Icon";
interface Props {
url: string;
}
const getFaviconUrlWithProvider = (url: string, provider: string) => {
try {
const searchParams = new URLSearchParams();
searchParams.set("domain", new URL(url).hostname);
return new URL(`?${searchParams.toString()}`, provider).toString();
} catch (error) {
return "";
}
};
const LinkFavicon = (props: Props) => {
const { url } = props;
const workspaceStore = useWorkspaceStore();
const faviconProvider = workspaceStore.profile.faviconProvider || "https://www.google.com/s2/favicons";
const [faviconUrl, setFaviconUrl] = useState<string>(getFaviconUrlWithProvider(url, faviconProvider));
const handleImgError = () => {
setFaviconUrl("");
};
return faviconUrl ? (
<img className="w-full h-auto rounded" src={faviconUrl} decoding="async" loading="lazy" onError={handleImgError} />
) : (
<Icon.CircleSlash className="w-full h-auto text-gray-400" strokeWidth={1.5} />
);
};
export default LinkFavicon;

View File

@ -8,8 +8,9 @@ import { Link } from "react-router-dom";
import { useUserStore, useViewStore } from "@/stores";
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
import { convertVisibilityFromPb } from "@/utils/visibility";
import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils";
import { absolutifyLink } from "../helpers/utils";
import Icon from "./Icon";
import LinkFavicon from "./LinkFavicon";
import ShortcutActionsDropdown from "./ShortcutActionsDropdown";
import VisibilityIcon from "./VisibilityIcon";
@ -24,7 +25,6 @@ const ShortcutCard = (props: Props) => {
const viewStore = useViewStore();
const creator = userStore.getUserById(shortcut.creatorId);
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
const favicon = getFaviconWithGoogleS2(shortcut.link);
useEffect(() => {
userStore.getOrFetchUserById(shortcut.creatorId);
@ -48,11 +48,7 @@ const ShortcutCard = (props: Props) => {
to={`/shortcut/${shortcut.id}`}
unstable_viewTransition
>
{favicon ? (
<img className="w-full h-auto rounded" src={favicon} decoding="async" loading="lazy" />
) : (
<Icon.CircleSlash className="w-full h-auto text-gray-400" />
)}
<LinkFavicon url={shortcut.link} />
</Link>
<div className="ml-1 w-[calc(100%-24px)] flex flex-col justify-start items-start">
<div className="w-full flex flex-row justify-start items-center">

View File

@ -1,17 +1,15 @@
import { Divider } from "@mui/joy";
import classNames from "classnames";
import { Link } from "react-router-dom";
import { getFaviconWithGoogleS2 } from "@/helpers/utils";
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
import Icon from "./Icon";
import LinkFavicon from "./LinkFavicon";
interface Props {
shortcut: Shortcut;
}
const ShortcutFrame = ({ shortcut }: Props) => {
const favicon = getFaviconWithGoogleS2(shortcut.link);
return (
<div className="w-full h-full flex flex-col justify-center items-center p-8">
<Link
@ -20,11 +18,7 @@ const ShortcutFrame = ({ shortcut }: Props) => {
target="_blank"
>
<div className={classNames("w-12 h-12 flex justify-center items-center overflow-clip rounded-lg shrink-0")}>
{favicon ? (
<img className="w-full h-auto" src={favicon} decoding="async" loading="lazy" />
) : (
<Icon.Globe2Icon className="w-full h-auto opacity-70" strokeWidth={1} />
)}
<LinkFavicon url={shortcut.link} />
</div>
<p className="text-lg font-medium leading-8 mt-2 truncate">{shortcut.title || shortcut.name}</p>
<p className="text-gray-500 truncate">{shortcut.description}</p>

View File

@ -1,8 +1,8 @@
import classNames from "classnames";
import { Link } from "react-router-dom";
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
import { getFaviconWithGoogleS2 } from "../helpers/utils";
import Icon from "./Icon";
import LinkFavicon from "./LinkFavicon";
import ShortcutActionsDropdown from "./ShortcutActionsDropdown";
interface Props {
@ -15,7 +15,6 @@ interface Props {
const ShortcutView = (props: Props) => {
const { shortcut, className, showActions, alwaysShowLink, onClick } = props;
const favicon = getFaviconWithGoogleS2(shortcut.link);
return (
<div
@ -26,11 +25,7 @@ const ShortcutView = (props: Props) => {
onClick={onClick}
>
<div className={classNames("w-5 h-5 flex justify-center items-center overflow-clip shrink-0")}>
{favicon ? (
<img className="w-full h-auto rounded" src={favicon} decoding="async" loading="lazy" />
) : (
<Icon.CircleSlash className="w-full h-auto text-gray-400" />
)}
<LinkFavicon url={shortcut.link} />
</div>
<div className="ml-2 w-full truncate">
{shortcut.title ? (