diff --git a/.changeset/rotten-coats-leave.md b/.changeset/rotten-coats-leave.md new file mode 100644 index 000000000..3b322cc2a --- /dev/null +++ b/.changeset/rotten-coats-leave.md @@ -0,0 +1,5 @@ +--- +"nostrudel": patch +--- + +Correctly handle web+nostr: links in search diff --git a/.changeset/shaggy-beers-mix.md b/.changeset/shaggy-beers-mix.md new file mode 100644 index 000000000..7883a199c --- /dev/null +++ b/.changeset/shaggy-beers-mix.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Add link to nostr army knife tool diff --git a/src/views/link/index.tsx b/src/views/link/index.tsx index d64d00e02..d6cc938b7 100644 --- a/src/views/link/index.tsx +++ b/src/views/link/index.tsx @@ -13,7 +13,7 @@ export default function NostrLinkView() { ); - const cleanLink = link.replace(/(web\+)?nostr:/, ""); + const cleanLink = link.replace(/(web\+)?nostr:(\/\/)?/, ""); const decoded = nip19.decode(cleanLink); switch (decoded.type) { diff --git a/src/views/note/index.tsx b/src/views/note/index.tsx index 03aacace2..bd144b28d 100644 --- a/src/views/note/index.tsx +++ b/src/views/note/index.tsx @@ -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}`); } diff --git a/src/views/search/index.tsx b/src/views/search/index.tsx index 23d77c441..3834ac0cd 100644 --- a/src/views/search/index.tsx +++ b/src/views/search/index.tsx @@ -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 ( diff --git a/src/views/tools/index.tsx b/src/views/tools/index.tsx index 966b105da..c5609fde5 100644 --- a/src/views/tools/index.tsx +++ b/src/views/tools/index.tsx @@ -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() { Tools - + + diff --git a/src/views/tools/nip19.tsx b/src/views/tools/nip19.tsx index 329329fa6..ea483d6f3 100644 --- a/src/views/tools/nip19.tsx +++ b/src/views/tools/nip19.tsx @@ -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 ( - + -
+ Public key - + {formState.errors.pubkey && {formState.errors.pubkey.message}} Relay url setValue("relay", v)} placeholder="wss://relay.example.com" /> {formState.errors.pubkey && {formState.errors.pubkey.message}} - +
{output && }
@@ -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(); + + const decode = handleSubmit((values) => { + try { + setOutput(nip19.decode(values.input)); + } catch (e) { + if (e instanceof Error) { + toast({ description: e.message }); + } + } + }); + + return ( + + +
+ + Encoded id + + {formState.errors.input && {formState.errors.input.message}} + + +
+ {output && ( + + {JSON.stringify(output, null, 2)} + + )} +
+
+ ); +} + export default function Nip19ToolsView() { return ( @@ -84,6 +130,8 @@ export default function Nip19ToolsView() { Encode + Decode + ); }