mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-26 17:52:18 +01:00
add link to nostr army knife
This commit is contained in:
parent
6930749ba3
commit
305f5e2922
5
.changeset/rotten-coats-leave.md
Normal file
5
.changeset/rotten-coats-leave.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": patch
|
||||
---
|
||||
|
||||
Correctly handle web+nostr: links in search
|
5
.changeset/shaggy-beers-mix.md
Normal file
5
.changeset/shaggy-beers-mix.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": minor
|
||||
---
|
||||
|
||||
Add link to nostr army knife tool
|
@ -13,7 +13,7 @@ export default function NostrLinkView() {
|
||||
</Alert>
|
||||
);
|
||||
|
||||
const cleanLink = link.replace(/(web\+)?nostr:/, "");
|
||||
const cleanLink = link.replace(/(web\+)?nostr:(\/\/)?/, "");
|
||||
const decoded = nip19.decode(cleanLink);
|
||||
|
||||
switch (decoded.type) {
|
||||
|
@ -15,8 +15,7 @@ function useNotePointer() {
|
||||
case "note":
|
||||
return { id: pointer.data as string, relays: [] };
|
||||
case "nevent":
|
||||
const p = pointer.data as nip19.EventPointer;
|
||||
return { id: p.id, relays: p.relays ?? [] };
|
||||
return { id: pointer.data.id, relays: pointer.data.relays ?? [] };
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
|
@ -88,14 +88,18 @@ export default function SearchView() {
|
||||
setSearch(searchParams.get("q") ?? "");
|
||||
}, [searchParams]);
|
||||
|
||||
const handleSearchText = (text: string) => {
|
||||
if (text.startsWith("nostr:") || text.startsWith("web+nostr:") || safeDecode(search)) {
|
||||
navigate({ pathname: "/l/" + encodeURIComponent(text) }, { replace: true });
|
||||
} else {
|
||||
setSearchParams({ q: text }, { replace: true });
|
||||
}
|
||||
};
|
||||
|
||||
// set the search when the form is submitted
|
||||
const handleSubmit = (e: React.SyntheticEvent) => {
|
||||
e.preventDefault();
|
||||
if (search.startsWith("nostr:") || safeDecode(search)) {
|
||||
navigate({ pathname: "/l/" + search }, { replace: true });
|
||||
} else {
|
||||
setSearchParams({ q: search }, { replace: true });
|
||||
}
|
||||
handleSearchText(search);
|
||||
};
|
||||
|
||||
// fetch search data from nostr.band
|
||||
@ -107,14 +111,7 @@ export default function SearchView() {
|
||||
}, [searchParams.get("q")]);
|
||||
|
||||
// handle data from qr code scanner
|
||||
const handleQrCodeData = (text: string) => {
|
||||
// if its a nostr: link pass it on the the link handler
|
||||
if (text.startsWith("nostr:")) {
|
||||
navigate({ pathname: "/l", search: `q=${text}` }, { replace: true });
|
||||
} else {
|
||||
setSearchParams({ q: text }, { replace: true });
|
||||
}
|
||||
};
|
||||
const handleQrCodeData = handleSearchText;
|
||||
|
||||
return (
|
||||
<Flex direction="column" overflowX="hidden" overflowY="auto" height="100%" p="2" gap="2">
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Button, Flex, Heading } from "@chakra-ui/react";
|
||||
import { Avatar, Button, Flex, Heading, Image, Link } from "@chakra-ui/react";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { ToolsIcon } from "../../components/icons";
|
||||
|
||||
@ -8,7 +8,16 @@ export default function ToolsHomeView() {
|
||||
<Heading>
|
||||
<ToolsIcon /> Tools
|
||||
</Heading>
|
||||
<Flex wrap="wrap">
|
||||
<Flex wrap="wrap" gap="4">
|
||||
<Button
|
||||
as={Link}
|
||||
href="https://nak.nostr.com/"
|
||||
isExternal
|
||||
target="_blank"
|
||||
leftIcon={<Image src="https://nak.nostr.com/favicon.ico" h="1.5em" />}
|
||||
>
|
||||
nostr army knife
|
||||
</Button>
|
||||
<Button as={RouterLink} to="./nip19">
|
||||
Nip-19 encode/decode
|
||||
</Button>
|
||||
|
@ -2,6 +2,7 @@ import {
|
||||
Button,
|
||||
Card,
|
||||
CardBody,
|
||||
Code,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormErrorMessage,
|
||||
@ -31,7 +32,7 @@ function EncodeForm() {
|
||||
|
||||
const [output, setOutput] = useState("");
|
||||
|
||||
const convert = handleSubmit((values) => {
|
||||
const encode = handleSubmit((values) => {
|
||||
try {
|
||||
const pubkey = normalizeToHex(values.pubkey);
|
||||
if (!pubkey) throw new Error("bad pubkey");
|
||||
@ -51,24 +52,24 @@ function EncodeForm() {
|
||||
});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<Card size="sm">
|
||||
<CardBody>
|
||||
<form onSubmit={convert}>
|
||||
<form onSubmit={encode}>
|
||||
<FormControl isInvalid={!!formState.errors.pubkey}>
|
||||
<FormLabel>Public key</FormLabel>
|
||||
<Input {...register("pubkey", { minLength: 8 })} placeholder="npub or hex" />
|
||||
<Input {...register("pubkey", { minLength: 8, required: true })} placeholder="npub or hex" />
|
||||
{formState.errors.pubkey && <FormErrorMessage>{formState.errors.pubkey.message}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
<FormControl isInvalid={!!formState.errors.pubkey}>
|
||||
<FormLabel>Relay url</FormLabel>
|
||||
<RelayUrlInput
|
||||
{...register("relay")}
|
||||
{...register("relay", { required: true })}
|
||||
onChange={(v) => setValue("relay", v)}
|
||||
placeholder="wss://relay.example.com"
|
||||
/>
|
||||
{formState.errors.pubkey && <FormErrorMessage>{formState.errors.pubkey.message}</FormErrorMessage>}
|
||||
<Button type="submit">Encode</Button>
|
||||
</FormControl>
|
||||
<Button type="submit">Encode</Button>
|
||||
</form>
|
||||
{output && <RawValue heading="nprofile" value={output} />}
|
||||
</CardBody>
|
||||
@ -76,6 +77,51 @@ function EncodeForm() {
|
||||
);
|
||||
}
|
||||
|
||||
function DecodeForm() {
|
||||
const toast = useToast();
|
||||
const { handleSubmit, register, formState, setValue } = useForm({
|
||||
mode: "onBlur",
|
||||
defaultValues: {
|
||||
input: "",
|
||||
},
|
||||
});
|
||||
|
||||
const [output, setOutput] = useState<Object>();
|
||||
|
||||
const decode = handleSubmit((values) => {
|
||||
try {
|
||||
setOutput(nip19.decode(values.input));
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
toast({ description: e.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Card size="sm">
|
||||
<CardBody>
|
||||
<form onSubmit={decode}>
|
||||
<FormControl isInvalid={!!formState.errors.input}>
|
||||
<FormLabel>Encoded id</FormLabel>
|
||||
<Input
|
||||
{...register("input", { minLength: 8, required: true })}
|
||||
placeholder="npub, note1, nevent, nprofile..."
|
||||
/>
|
||||
{formState.errors.input && <FormErrorMessage>{formState.errors.input.message}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
<Button type="submit">Decode</Button>
|
||||
</form>
|
||||
{output && (
|
||||
<Code whiteSpace="pre" overflowX="auto" width="100%">
|
||||
{JSON.stringify(output, null, 2)}
|
||||
</Code>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Nip19ToolsView() {
|
||||
return (
|
||||
<Flex direction="column" gap="4" p="4">
|
||||
@ -84,6 +130,8 @@ export default function Nip19ToolsView() {
|
||||
</Heading>
|
||||
<Heading size="sm">Encode</Heading>
|
||||
<EncodeForm />
|
||||
<Heading size="sm">Decode</Heading>
|
||||
<DecodeForm />
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user