mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-19 03:51:34 +02:00
Merge branch 'next'
This commit is contained in:
5
.changeset/real-dancers-punch.md
Normal file
5
.changeset/real-dancers-punch.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Only fetch open graph metadata for html urls
|
@@ -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">
|
||||||
|
@@ -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 });
|
||||||
|
const contentType = res.headers.get("content-type");
|
||||||
|
|
||||||
|
if (contentType?.includes("text/html")) {
|
||||||
|
const html = await res.text();
|
||||||
return extractMetaTags(html);
|
return extractMetaTags(html);
|
||||||
|
} else controller.abort();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
return null;
|
return null;
|
||||||
}, [url.toString()]);
|
}, [url.toString()]);
|
||||||
|
@@ -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");
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user