forked from Kieran/snort
feat: render image/video in link previews
This commit is contained in:
parent
78bfa57628
commit
f6a51fd80b
@ -4,6 +4,7 @@ import { CSSProperties, useEffect, useState } from "react";
|
|||||||
import Spinner from "Icons/Spinner";
|
import Spinner from "Icons/Spinner";
|
||||||
import SnortApi, { LinkPreviewData } from "SnortApi";
|
import SnortApi, { LinkPreviewData } from "SnortApi";
|
||||||
import useImgProxy from "Hooks/useImgProxy";
|
import useImgProxy from "Hooks/useImgProxy";
|
||||||
|
import { MediaElement } from "Element/MediaElement";
|
||||||
|
|
||||||
async function fetchUrlPreviewInfo(url: string) {
|
async function fetchUrlPreviewInfo(url: string) {
|
||||||
const api = new SnortApi();
|
const api = new SnortApi();
|
||||||
@ -21,8 +22,12 @@ const LinkPreview = ({ url }: { url: string }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const data = await fetchUrlPreviewInfo(url);
|
const data = await fetchUrlPreviewInfo(url);
|
||||||
if (data && data.image) {
|
if (data) {
|
||||||
setPreview(data);
|
const type = data.og_tags?.find(a => a[0].toLowerCase() === "og:type");
|
||||||
|
const canPreviewType = type?.[1].startsWith("image") || type?.[1].startsWith("video") || false;
|
||||||
|
if (canPreviewType || data.image) {
|
||||||
|
setPreview(data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setPreview(null);
|
setPreview(null);
|
||||||
}
|
}
|
||||||
@ -36,14 +41,37 @@ const LinkPreview = ({ url }: { url: string }) => {
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
const backgroundImage = preview?.image ? `url(${proxy(preview?.image)})` : "";
|
function previewElement() {
|
||||||
const style = { "--img-url": backgroundImage } as CSSProperties;
|
const type = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:type")?.[1];
|
||||||
|
if (type?.startsWith("video")) {
|
||||||
|
const urlTags = ["og:video:secure_url", "og:video:url", "og:video"];
|
||||||
|
const link = preview?.og_tags?.find(a => urlTags.includes(a[0].toLowerCase()))?.[1];
|
||||||
|
const videoType = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:video:type")?.[1] ?? "video/mp4";
|
||||||
|
if (link) {
|
||||||
|
return <MediaElement url={link} mime={videoType} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type?.startsWith("image")) {
|
||||||
|
const urlTags = ["og:image:secure_url", "og:image:url", "og:image"];
|
||||||
|
const link = preview?.og_tags?.find(a => urlTags.includes(a[0].toLowerCase()))?.[1];
|
||||||
|
const videoType = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:image:type")?.[1] ?? "image/png";
|
||||||
|
if (link) {
|
||||||
|
return <MediaElement url={link} mime={videoType} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preview?.image) {
|
||||||
|
const backgroundImage = preview?.image ? `url(${proxy(preview?.image)})` : "";
|
||||||
|
const style = { "--img-url": backgroundImage } as CSSProperties;
|
||||||
|
return <div className="link-preview-image" style={style}></div>;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="link-preview-container">
|
<div className="link-preview-container">
|
||||||
{preview && (
|
{preview && (
|
||||||
<a href={url} onClick={e => e.stopPropagation()} target="_blank" rel="noreferrer" className="ext">
|
<a href={url} onClick={e => e.stopPropagation()} target="_blank" rel="noreferrer" className="ext">
|
||||||
{preview?.image && <div className="link-preview-image" style={style} />}
|
{previewElement()}
|
||||||
<p className="link-preview-title">
|
<p className="link-preview-title">
|
||||||
{preview?.title}
|
{preview?.title}
|
||||||
{preview?.description && (
|
{preview?.description && (
|
||||||
|
@ -45,6 +45,7 @@ export interface LinkPreviewData {
|
|||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
image?: string;
|
image?: string;
|
||||||
|
og_tags?: Array<[name: string, value: string]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SnortApi {
|
export default class SnortApi {
|
||||||
|
Loading…
Reference in New Issue
Block a user