add tools link to nav

This commit is contained in:
hzrd149 2023-08-22 13:19:18 -05:00
parent b7deb163fd
commit ed0408de76
6 changed files with 41 additions and 147 deletions

View File

@ -28,7 +28,6 @@ import DirectMessageChatView from "./views/messages/chat";
import NostrLinkView from "./views/link";
import UserReportsTab from "./views/user/reports";
import ToolsHomeView from "./views/tools";
import Nip19ToolsView from "./views/tools/nip19";
import UserAboutTab from "./views/user/about";
import UserLikesTab from "./views/user/likes";
import useSetColorMode from "./hooks/use-set-color-mode";
@ -116,10 +115,7 @@ const router = createHashRouter([
{ path: "profile", element: <ProfileView /> },
{
path: "tools",
children: [
{ path: "", element: <ToolsHomeView /> },
{ path: "nip19", element: <Nip19ToolsView /> },
],
children: [{ path: "", element: <ToolsHomeView /> }],
},
{
path: "streams",

View File

@ -7,25 +7,25 @@ import DesktopSideNav from "./desktop-side-nav";
import MobileBottomNav from "./mobile-bottom-nav";
export default function Layout({ children }: { children: React.ReactNode }) {
const showSideNav = useBreakpointValue({ base: true, md: false });
const isMobile = useBreakpointValue({ base: true, md: false });
return (
<>
<ReloadPrompt mb="2" />
<Container size="lg" display="flex" padding="0" gap="4" alignItems="flex-start">
{!showSideNav && <DesktopSideNav position="sticky" top="0" />}
{!isMobile && <DesktopSideNav position="sticky" top="0" />}
<Flex
flexGrow={1}
direction="column"
w="full"
overflowX="hidden"
overflowY="visible"
pb={showSideNav ? "14" : 0}
pb={isMobile ? "14" : 0}
minH="50vh"
>
<ErrorBoundary>{children}</ErrorBoundary>
</Flex>
{showSideNav && (
{isMobile && (
<MobileBottomNav
position="fixed"
bottom="0"

View File

@ -10,6 +10,7 @@ import {
RelayIcon,
SearchIcon,
SettingsIcon,
ToolsIcon,
} from "../icons";
export default function NavItems({ isInDrawer = false }: { isInDrawer?: boolean }) {
@ -47,6 +48,9 @@ export default function NavItems({ isInDrawer = false }: { isInDrawer?: boolean
<Button onClick={() => navigate("/map")} leftIcon={<MapIcon />} justifyContent="flex-start">
Map
</Button>
<Button onClick={() => navigate("/tools")} leftIcon={<ToolsIcon />} justifyContent="flex-start">
Tools
</Button>
<Divider my="2" />
<Button onClick={() => navigate("/settings")} leftIcon={<SettingsIcon />} justifyContent="flex-start">
Settings

View File

@ -43,9 +43,6 @@ export default function SettingsView() {
</Accordion>
</FormProvider>
<Flex gap="4" padding="4" alignItems="center">
<Button as={RouterLink} to="/tools" leftIcon={<ToolsIcon />}>
Tools
</Button>
<Link isExternal href="https://github.com/hzrd149/nostrudel">
<GithubIcon /> Github
</Link>

View File

@ -1,6 +1,7 @@
import { Avatar, Button, Flex, Heading, Image, Link } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { ToolsIcon } from "../../components/icons";
import OpenGraphCard from "../../components/open-graph-card";
export default function ToolsHomeView() {
return (
@ -9,6 +10,15 @@ export default function ToolsHomeView() {
<ToolsIcon /> Tools
</Heading>
<Flex wrap="wrap" gap="4">
<Button
as={Link}
href="https://w3.do/"
isExternal
target="_blank"
leftIcon={<Image src="https://w3.do/favicon.ico" h="1.5em" />}
>
URL Shortener
</Button>
<Button
as={Link}
href="https://nak.nostr.com/"
@ -18,8 +28,28 @@ export default function ToolsHomeView() {
>
nostr army knife
</Button>
<Button as={RouterLink} to="./nip19">
Nip-19 encode/decode
<Button
as={Link}
href="https://nostrdebug.com/"
isExternal
target="_blank"
leftIcon={<Image src="https://nostrdebug.com/favicon.ico" h="1.5em" />}
>
Nostr Debug
</Button>
<Button
as={Link}
href="https://www.nostrapps.com/"
isExternal
target="_blank"
leftIcon={
<Image
src="https://uploads-ssl.webflow.com/641d0d46d5c124ac928a6027/64b1dd06d59d8f1e530d2926_32x32.png"
h="1.5em"
/>
}
>
Nostr Apps
</Button>
</Flex>
</Flex>

View File

@ -1,133 +0,0 @@
import {
Button,
Card,
CardBody,
Code,
Flex,
FormControl,
FormErrorMessage,
FormLabel,
Heading,
Input,
useToast,
} from "@chakra-ui/react";
import { ToolsIcon } from "../../components/icons";
import { useForm } from "react-hook-form";
import { RelayUrlInput } from "../../components/relay-url-input";
import { useState } from "react";
import { normalizeToHex } from "../../helpers/nip19";
import { nip19 } from "nostr-tools";
import { normalizeRelayUrl } from "../../helpers/url";
import RawValue from "../../components/debug-modals/raw-value";
function EncodeForm() {
const toast = useToast();
const { handleSubmit, register, formState, setValue } = useForm({
mode: "onBlur",
defaultValues: {
pubkey: "",
relay: "",
},
});
const [output, setOutput] = useState("");
const encode = handleSubmit((values) => {
try {
const pubkey = normalizeToHex(values.pubkey);
if (!pubkey) throw new Error("bad pubkey");
const relay = normalizeRelayUrl(values.relay);
const nprofile = nip19.nprofileEncode({
pubkey,
relays: [relay],
});
setOutput(nprofile);
} catch (e) {
if (e instanceof Error) toast({ description: e.message, status: "error" });
}
});
return (
<Card size="sm">
<CardBody>
<form onSubmit={encode}>
<FormControl isInvalid={!!formState.errors.pubkey}>
<FormLabel>Public key</FormLabel>
<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", { required: true })}
onChange={(v) => setValue("relay", v)}
placeholder="wss://relay.example.com"
/>
{formState.errors.pubkey && <FormErrorMessage>{formState.errors.pubkey.message}</FormErrorMessage>}
</FormControl>
<Button type="submit">Encode</Button>
</form>
{output && <RawValue heading="nprofile" value={output} />}
</CardBody>
</Card>
);
}
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, status: "error" });
}
});
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">
<Heading>
<ToolsIcon /> Nip-19 Tools
</Heading>
<Heading size="sm">Encode</Heading>
<EncodeForm />
<Heading size="sm">Decode</Heading>
<DecodeForm />
</Flex>
);
}