Merge branch 'next'

This commit is contained in:
hzrd149
2023-06-29 12:33:31 -05:00
5 changed files with 30 additions and 12 deletions

View File

@@ -0,0 +1,5 @@
---
"nostrudel": patch
---
Only fetch open graph metadata for html urls

View File

@@ -15,7 +15,7 @@ export default function OpenGraphCard({ url, ...props }: { url: URL } & Omit<Car
return ( return (
<LinkBox borderRadius="lg" borderWidth={1} overflow="hidden" {...props}> <LinkBox borderRadius="lg" borderWidth={1} overflow="hidden" {...props}>
{data.ogImage?.map((ogImage) => ( {data.ogImage?.map((ogImage) => (
<Image src={ogImage.url} mx="auto" /> <Image key={ogImage.url} src={ogImage.url} mx="auto" />
))} ))}
<Box m="2" mt="4"> <Box m="2" mt="4">

View File

@@ -2,11 +2,22 @@ import { useAsync } from "react-use";
import extractMetaTags from "../lib/open-graph-scraper/extract"; import extractMetaTags from "../lib/open-graph-scraper/extract";
import { fetchWithCorsFallback } from "../helpers/cors"; import { fetchWithCorsFallback } from "../helpers/cors";
const pageExtensions = [".html", ".php", "htm"];
export default function useOpenGraphData(url: URL) { export default function useOpenGraphData(url: URL) {
return useAsync(async () => { return useAsync(async () => {
const controller = new AbortController();
const ext = url.pathname.match(/\.[\w+d]+$/)?.[0];
if (ext && !pageExtensions.includes(ext)) return null;
try { try {
const html = await fetchWithCorsFallback(url).then((res) => res.text()); const res = await fetchWithCorsFallback(url, { signal: controller.signal });
return extractMetaTags(html); const contentType = res.headers.get("content-type");
if (contentType?.includes("text/html")) {
const html = await res.text();
return extractMetaTags(html);
} else controller.abort();
} catch (e) {} } catch (e) {}
return null; return null;
}, [url.toString()]); }, [url.toString()]);

View File

@@ -1,7 +1,7 @@
import { DraftNostrEvent, NostrEvent } from "../types/nostr-event"; import { DraftNostrEvent, NostrEvent } from "../types/nostr-event";
import { Account } from "./account"; import { Account } from "./account";
import db from "./db"; import db from "./db";
import { nip04, signEvent, getEventHash, getPublicKey } from "nostr-tools"; import { nip04, getPublicKey, finishEvent } from "nostr-tools";
const decryptedKeys = new Map<string, string>(); const decryptedKeys = new Map<string, string>();
@@ -85,12 +85,7 @@ class SigningService {
} else if (account?.secKey) { } else if (account?.secKey) {
const secKey = await this.decryptSecKey(account); const secKey = await this.decryptSecKey(account);
const tmpDraft = { ...draft, pubkey: getPublicKey(secKey) }; const tmpDraft = { ...draft, pubkey: getPublicKey(secKey) };
const signature = signEvent(tmpDraft, secKey); const event = finishEvent(tmpDraft, secKey) as NostrEvent;
const event: NostrEvent = {
...tmpDraft,
id: getEventHash(tmpDraft),
sig: signature,
};
return event; return event;
} else throw new Error("No signing method"); } else throw new Error("No signing method");

View File

@@ -12,10 +12,10 @@ import {
useDisclosure, useDisclosure,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { useSearchParams, Link as RouterLink, useNavigate } from "react-router-dom"; import { useSearchParams, Link as RouterLink, useNavigate } from "react-router-dom";
import { useAsync } from "react-use"; import { useAsync } from "react-use";
import { LightningIcon, QrCodeIcon } from "../../components/icons"; import { ClipboardIcon, LightningIcon, QrCodeIcon } from "../../components/icons";
import { UserAvatarLink } from "../../components/user-avatar-link"; import { UserAvatarLink } from "../../components/user-avatar-link";
import { UserDnsIdentityIcon } from "../../components/user-dns-identity-icon"; import { UserDnsIdentityIcon } from "../../components/user-dns-identity-icon";
import ZapModal from "../../components/zap-modal"; import ZapModal from "../../components/zap-modal";
@@ -98,6 +98,10 @@ export default function SearchView() {
} }
}; };
const readClipboard = useCallback(async () => {
handleSearchText(await navigator.clipboard.readText());
}, []);
// set the search when the form is submitted // set the search when the form is submitted
const handleSubmit = (e: React.SyntheticEvent) => { const handleSubmit = (e: React.SyntheticEvent) => {
e.preventDefault(); e.preventDefault();
@@ -122,6 +126,9 @@ export default function SearchView() {
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Flex gap="2"> <Flex gap="2">
<IconButton onClick={openScanner} icon={<QrCodeIcon />} aria-label="Qr Scanner" /> <IconButton onClick={openScanner} icon={<QrCodeIcon />} aria-label="Qr Scanner" />
{!!navigator.clipboard.readText && (
<IconButton onClick={readClipboard} icon={<ClipboardIcon />} aria-label="Read clipboard" />
)}
<Input type="search" value={search} onChange={(e) => setSearch(e.target.value)} /> <Input type="search" value={search} onChange={(e) => setSearch(e.target.value)} />
<Button type="submit" isLoading={loading}> <Button type="submit" isLoading={loading}>
Search Search