Skip to content

Commit

Permalink
feat: render embeds from link preview
Browse files Browse the repository at this point in the history
closes #693
  • Loading branch information
v0l committed Apr 12, 2024
1 parent 5292b88 commit 8d306ce
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 15 deletions.
34 changes: 34 additions & 0 deletions packages/app/src/Components/Embed/GenericPlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState } from "react";

import Icon from "../Icons/Icon";
import { ProxyImg } from "../ProxyImg";

export default function GenericPlayer({ url, poster }: { url: string; poster: string }) {
const [play, setPlay] = useState(false);

if (!play) {
return (
<div
className="relative aspect-video"
onClick={e => {
e.preventDefault();
e.stopPropagation();
setPlay(true);
}}>
<ProxyImg className="absolute" src={poster} />
<div className="absolute w-full h-full opacity-0 hover:opacity-100 hover:bg-black/30 flex items-center justify-center transition">
<Icon name="play-square-outline" size={50} />
</div>
</div>
);
}
return (
<iframe
className="aspect-video w-full"
src={url}
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen={true}
/>
);
}
4 changes: 3 additions & 1 deletion packages/app/src/Components/Embed/LinkPreview.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
font-size: 12px;
}

.link-preview-image {
.link-preview-container img,
.link-preview-container video,
.link-preview-container iframe {
margin: 0 0 15px 0 !important;
border-radius: 0 !important;
background-image: var(--img-url);
Expand Down
14 changes: 8 additions & 6 deletions packages/app/src/Components/Embed/LinkPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import "./LinkPreview.css";

import { CSSProperties, useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { LRUCache } from "typescript-lru-cache";

import { MediaElement } from "@/Components/Embed/MediaElement";
import Spinner from "@/Components/Icons/Spinner";
import { LinkPreviewData, NostrServices } from "@/External/NostrServices";
import useImgProxy from "@/Hooks/useImgProxy";

import { ProxyImg } from "../ProxyImg";
import GenericPlayer from "./GenericPlayer";

async function fetchUrlPreviewInfo(url: string) {
const api = new NostrServices("https://nostr.api.v0l.io");
Expand All @@ -23,7 +25,6 @@ const cache = new LRUCache<string, LinkPreviewData>({

const LinkPreview = ({ url }: { url: string }) => {
const [preview, setPreview] = useState<LinkPreviewData | null>(cache.get(url));
const { proxy } = useImgProxy();

useEffect(() => {
(async () => {
Expand Down Expand Up @@ -59,6 +60,9 @@ const LinkPreview = ({ url }: { url: string }) => {
if (link && videoType.startsWith("video/")) {
return <MediaElement url={link} mime={videoType} />;
}
if (link && videoType.startsWith("text/html") && preview?.image) {
return <GenericPlayer url={link} poster={preview?.image} />;
}
}
if (type?.startsWith("image")) {
const urlTags = ["og:image:secure_url", "og:image:url", "og:image"];
Expand All @@ -69,9 +73,7 @@ const LinkPreview = ({ url }: { url: string }) => {
}
}
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 <ProxyImg src={preview?.image} />;
}
return null;
}
Expand Down
8 changes: 1 addition & 7 deletions packages/app/src/Components/Embed/TwitchEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ const TwitchEmbed = ({ link }: { link: string }) => {
const args = `?channel=${channel}&parent=${window.location.hostname}&muted=true`;
return (
<>
<iframe
src={`https://player.twitch.tv/${args}`}
className="w-max"
allowFullScreen={true}
// eslint-disable-next-line react/no-unknown-property
credentialless=""
/>
<iframe src={`https://player.twitch.tv/${args}`} className="w-max" allowFullScreen={true} />
<a href={link} target="_blank" rel="noreferrer" onClick={e => e.stopPropagation()} className="ext">
{link}
</a>
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/Components/Event/Note/Note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function Note(props: NoteProps) {
<div className="body" onClick={e => goToEvent(e, ev)}>
<NoteText {...props} translated={translated} showTranslation={showTranslation} />
{translated && <TranslationInfo translated={translated} setShowTranslation={setShowTranslation} />}
{ev.kind === EventKind.Polls && <Poll ev={ev} />}
{ev.kind === EventKind.Polls && <Poll ev={ev} zaps={[]} />}
{optionsMerged.showFooter && (
<div className="mt-4">
<NoteFooter ev={ev} replyCount={props.threadChains?.get(chainKey(ev))?.length} />
Expand Down
8 changes: 8 additions & 0 deletions packages/system/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,17 +380,25 @@ export class Query extends EventEmitter<QueryEvents> {
}

#canSendQuery(c: Connection, q: BuiltRawReqFilter) {
// query is not for this relay
if (q.relay && q.relay !== c.Address) {
return false;
}
// cannot send unless relay is tagged on ephemeral relay connection
if (!q.relay && c.Ephemeral) {
this.#log("Cant send non-specific REQ to ephemeral connection %O %O %O", q, q.relay, c);
return false;
}
// search not supported, cant send
if (q.filters.some(a => a.search) && !c.supportsNip(Nips.Search)) {
this.#log("Cant send REQ to non-search relay", c.Address);
return false;
}
// query already closed, cant send
if (this.canRemove()) {
this.#log("Cant send REQ when query is closed", this.id, q);
return false;
}
return true;
}

Expand Down

0 comments on commit 8d306ce

Please sign in to comment.