mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-12 13:49:33 +02:00
add tools link to nav
This commit is contained in:
parent
b7deb163fd
commit
ed0408de76
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user